Unneeded code

This commit is contained in:
David Carley
2022-07-12 19:38:02 -07:00
parent 9a397d565f
commit 614e7f62cb
18 changed files with 0 additions and 1337 deletions

View File

@@ -19,7 +19,6 @@ setup(
packages=[
'bbctrl',
'inevent',
'lcd',
'camotics',
'iw_parse'
],

View File

@@ -1,143 +0,0 @@
/******************************************************************************\
This file is part of the Buildbotics firmware.
Copyright (c) 2015 - 2018, Buildbotics LLC
All rights reserved.
This file ("the software") is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License,
version 2 as published by the Free Software Foundation. You should
have received a copy of the GNU General Public License, version 2
along with the software. If not, see <http://www.gnu.org/licenses/>.
The software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the software. If not, see
<http://www.gnu.org/licenses/>.
For information regarding this software email:
"Joseph Coffland" <joseph@buildbotics.com>
\******************************************************************************/
#include "lcd.h"
#include "rtc.h"
#include "hardware.h"
#include "command.h"
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <stdbool.h>
void lcd_init(uint8_t addr) {
// Enable I2C master
TWIC.MASTER.BAUD = F_CPU / 2 / 100000 - 5; // 100 KHz
TWIC.MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
TWIC.MASTER.CTRLB = TWI_MASTER_TIMEOUT_DISABLED_gc;
TWIC.MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
_delay_ms(50);
lcd_nibble(addr, 3 << 4); // Home
_delay_ms(50);
lcd_nibble(addr, 3 << 4); // Home
_delay_ms(50);
lcd_nibble(addr, 3 << 4); // Home
lcd_nibble(addr, 2 << 4); // 4-bit
lcd_write(addr,
LCD_FUNCTION_SET | LCD_2_LINE | LCD_5x8_DOTS | LCD_4_BIT_MODE, 0);
lcd_write(addr, LCD_DISPLAY_CONTROL | LCD_DISPLAY_ON, 0);
lcd_write(addr, LCD_ENTRY_MODE_SET | LCD_ENTRY_SHIFT_INC, 0);
lcd_write(addr, LCD_CLEAR_DISPLAY, 0);
lcd_write(addr, LCD_RETURN_HOME, 0);
}
static void _master_wait() {
#ifdef __AVR__
while (!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm)) continue;
#endif
}
static void _write_i2c(uint8_t addr, uint8_t data) {
data |= BACKLIGHT_BIT;
TWIC.MASTER.ADDR = addr << 1;
_master_wait();
TWIC.MASTER.DATA = data;
_master_wait();
TWIC.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
_delay_us(100);
}
void lcd_nibble(uint8_t addr, uint8_t data) {
_write_i2c(addr, data);
_write_i2c(addr, data | ENABLE_BIT);
_delay_us(500);
_write_i2c(addr, data & ~ENABLE_BIT);
_delay_us(100);
}
void lcd_write(uint8_t addr, uint8_t cmd, uint8_t flags) {
lcd_nibble(addr, flags | (cmd & 0xf0));
lcd_nibble(addr, flags | ((cmd << 4) & 0xf0));
}
void lcd_goto(uint8_t addr, uint8_t x, uint8_t y) {
static uint8_t row[] = {0, 64, 20, 84};
lcd_write(addr, LCD_SET_DDRAM_ADDR | (row[y] + x), 0);
}
void lcd_putchar(uint8_t addr, uint8_t c) {
lcd_write(addr, c, REG_SELECT_BIT);
}
void lcd_pgmstr(uint8_t addr, const char *s) {
while (true) {
char c = pgm_read_byte(s++);
if (!c) break;
lcd_putchar(addr, c);
}
}
void _splash(uint8_t addr) {
lcd_init(addr);
lcd_goto(addr, 1, 1);
lcd_pgmstr(addr, PSTR("Controller booting"));
lcd_goto(addr, 3, 2);
lcd_pgmstr(addr, PSTR("Please wait..."));
}
void lcd_splash() {
wdt_disable();
_splash(0x27);
_splash(0x3f);
wdt_enable(WDTO_250MS);
}
void lcd_rtc_callback() {
// Display the splash if we haven't gotten any commands in 1sec since boot
if (!command_is_active() && rtc_get_time() == 1000)
lcd_splash();
}

View File

@@ -1,103 +0,0 @@
/******************************************************************************\
This file is part of the Buildbotics firmware.
Copyright (c) 2015 - 2018, Buildbotics LLC
All rights reserved.
This file ("the software") is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License,
version 2 as published by the Free Software Foundation. You should
have received a copy of the GNU General Public License, version 2
along with the software. If not, see <http://www.gnu.org/licenses/>.
The software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the software. If not, see
<http://www.gnu.org/licenses/>.
For information regarding this software email:
"Joseph Coffland" <joseph@buildbotics.com>
\******************************************************************************/
#pragma once
#include "pgmspace.h"
#include <stdint.h>
// Control flags
enum {
REG_SELECT_BIT = 1 << 0,
READ_BIT = 1 << 1,
ENABLE_BIT = 1 << 2,
BACKLIGHT_BIT = 1 << 3,
};
// Commands
enum {
LCD_CLEAR_DISPLAY = 1 << 0,
LCD_RETURN_HOME = 1 << 1,
LCD_ENTRY_MODE_SET = 1 << 2,
LCD_DISPLAY_CONTROL = 1 << 3,
LCD_CURSOR_SHIFT = 1 << 4,
LCD_FUNCTION_SET = 1 << 5,
LCD_SET_CGRAM_ADDR = 1 << 6,
LCD_SET_DDRAM_ADDR = 1 << 7,
};
// Entry Mode Set flags
#define LCD_ENTRY_SHIFT_DISPLAY (1 << 0)
#define LCD_ENTRY_SHIFT_INC (1 << 1)
#define LCD_ENTRY_SHIFT_DEC (0 << 1)
// Display Control flags
#define LCD_BLINK_ON (1 << 0)
#define LCD_BLINK_OFF (0 << 0)
#define LCD_CURSOR_ON (1 << 1)
#define LCD_CURSOR_OFF (0 << 1)
#define LCD_DISPLAY_ON (1 << 2)
#define LCD_DISPLAY_OFF (0 << 2)
// Cursor Shift flags
#define LCD_SHIFT_RIGHT (1 << 2)
#define LCD_SHIFT_LEFT (0 << 2)
#define LCD_SHIFT_DISPLAY (1 << 3)
#define LCD_SHIFT_CURSOR (0 << 3)
// Function Set flags
#define LCD_5x11_DOTS (1 << 2)
#define LCD_5x8_DOTS (0 << 2)
#define LCD_2_LINE (1 << 3)
#define LCD_1_LINE (0 << 3)
#define LCD_8_BIT_MODE (1 << 4)
#define LCD_4_BIT_MODE (0 << 4)
// Text justification flags
enum {
JUSTIFY_LEFT = 0,
JUSTIFY_RIGHT = 1,
JUSTIFY_CENTER = 2,
};
void lcd_init(uint8_t addr);
void lcd_nibble(uint8_t addr, uint8_t data);
void lcd_write(uint8_t addr, uint8_t cmd, uint8_t flags);
void lcd_goto(uint8_t addr, uint8_t x, uint8_t y);
void lcd_putchar(uint8_t addr, uint8_t c);
void lcd_pgmstr(uint8_t addr, const char *s);
void lcd_splash();
void lcd_rtc_callback();

View File

@@ -30,7 +30,6 @@
#include "switch.h"
#include "analog.h"
#include "motor.h"
#include "lcd.h"
#include "vfd_spindle.h"
#include <avr/io.h>
@@ -46,7 +45,6 @@ static uint32_t ticks;
ISR(RTC_OVF_vect) {
ticks++;
lcd_rtc_callback();
switch_rtc_callback();
analog_rtc_callback();
vfd_spindle_rtc_callback();

View File

@@ -1,20 +0,0 @@
# Makefile for Bulidbotics step-test
PROJECT = step-test
MCU = atxmega192a3u
CLOCK = 32000000
# SRC
SRC = usart.c lcd.c pins.c hardware.c
SRC := $(wildcard *.c) $(patsubst %,../src/%,$(SRC))
include ../Makefile.common
CFLAGS += -I../src -I.
# Build
all: $(PROJECT).hex size
$(PROJECT).elf: $(SRC)
$(CC) $(SRC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@
.PHONY: all

View File

@@ -1,187 +0,0 @@
#!/usr/bin/env python3
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import sys, serial, argparse
import numpy as np
import math
import json
from time import sleep
from collections import deque
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib.animation as animation
MM_PER_STEP = 5 * 1.8 / 360 / 32
SAMPLES_PER_MIN = 6000
class Plot:
def __init__(self, port, baud, max_len):
# Open serial port
self.sp = serial.Serial(port, baud)
# Create data series
self.series = []
for i in range(5):
self.series.append(deque([0.0] * max_len))
# Init vars
self.max_len = max_len
self.incoming = ''
self.last = [None] * 4
# Open velocity log
ts = datetime.now().strftime('%Y-%m-%d-%H:%M:%S')
self.log = open('velocity-%s.log' % ts, 'w')
# Add new series data
def add(self, i, value):
self.series[i].pop()
self.series[i].appendleft(value)
def update_text(self, text, vel, data):
text[4].set_text('V {0:8,.2f}'.format(vel))
for i in range(4):
text[i].set_text('{} {:11,}'.format('XYZA'[i], int(data[i])))
def update(self, frame, axes, text):
# Read new data
try:
data = self.sp.read(self.sp.in_waiting)
self.incoming += data.decode('utf-8')
except Exception as e:
print(e)
return
while True:
# Parse lines
i = self.incoming.find('\n')
if i == -1: break
line = self.incoming[0:i]
self.incoming = self.incoming[i + 1:]
# Handle reset
if line.find('RESET') != -1:
self.update_text(text, 0, [0] * 4)
self.log.write(line + '\n')
self.last = [None] * 4
continue
# Parse data
try:
data = [float(value) for value in line.split(',')]
except ValueError: continue
if len(data) != 4: continue
# Compute axis velocities
v = [] # Axis velocity
totalV = 0 # Tool velocity
for i in range(4):
if self.last[i] is not None:
delta = self.last[i] - data[i]
v.append(delta * MM_PER_STEP * SAMPLES_PER_MIN) # mm/min
totalV += math.pow(v[i], 2)
self.last[i] = data[i]
# Compute tool velocity
totalV = math.sqrt(totalV)
# Update position and velocity text
self.update_text(text, totalV, data)
# Don't update plots when not moving
if totalV == 0: continue
# Add new data
for i in range(4): self.add(i, v[i])
self.add(4, totalV)
# Update plots
for i in range(5):
axes[i].set_data(range(self.max_len), self.series[i])
self.log.write(line + '\n')
def close(self):
self.sp.flush()
self.sp.close()
if __name__ == '__main__':
# Parse command line arguments
description = "Plot velocity data in real-time"
parser = argparse.ArgumentParser(description = description)
parser.add_argument('-p', '--port', default = '/dev/ttyUSB0')
parser.add_argument('-b', '--baud', default = 115200, type = int)
parser.add_argument('-m', '--max-width', default = 2000, type = int)
args = parser.parse_args()
# Create plot
plot = Plot(args.port, args.baud, args.max_width)
fig = plt.figure()
ax = plt.axes(xlim = (0, args.max_width), ylim = (-10000, 10000))
axes = []
axes_text = []
# Setup position and velocity text fields
font = dict(fontsize = 14, family = 'monospace')
axes_text.append(plt.text(0, 11700, '', **font))
axes_text.append(plt.text(800, 11700, '', **font))
axes_text.append(plt.text(0, 10500, '', **font))
axes_text.append(plt.text(800, 10500, '', **font))
axes_text.append(plt.text(1500, 11700, '', **font))
# Create axes
for i in range(5):
axes.append(ax.plot([], [])[0])
# Set text color to match axis color
axes_text[i].set_color(axes[i].get_color())
# Initial text views
plot.update_text(axes_text, 0, [0] * 4)
# Set up animation
anim = animation.FuncAnimation(fig, plot.update, fargs = [axes, axes_text],
interval = 100)
# Run
plt.show()
plot.close()

View File

@@ -1,230 +0,0 @@
/******************************************************************************\
This file is part of the Buildbotics firmware.
Copyright (c) 2015 - 2018, Buildbotics LLC
All rights reserved.
This file ("the software") is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License,
version 2 as published by the Free Software Foundation. You should
have received a copy of the GNU General Public License, version 2
along with the software. If not, see <http://www.gnu.org/licenses/>.
The software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the software. If not, see
<http://www.gnu.org/licenses/>.
For information regarding this software email:
"Joseph Coffland" <joseph@buildbotics.com>
\******************************************************************************/
#include "config.h"
#include "hardware.h"
#include "usart.h"
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdint.h>
#include <stdio.h>
#define RESET_PIN SPI_MOSI_PIN
void rtc_init() {}
static struct {
uint8_t step_pin;
uint8_t dir_pin;
TC0_t *timer;
volatile int16_t high;
volatile bool reading;
} channel[4] = {
{STEP_X_PIN, DIR_X_PIN, &TCC0, 0},
{STEP_Y_PIN, DIR_Y_PIN, &TCD0, 0},
{STEP_Z_PIN, DIR_Z_PIN, &TCE0, 0},
{STEP_A_PIN, DIR_A_PIN, &TCF0, 0},
};
static int reset = 0;
void channel_reset(int i) {channel[i].timer->CNT = channel[i].high = 0;}
#define EVSYS_CHMUX(CH) (&EVSYS_CH0MUX)[CH]
#define EVSYS_CHCTRL(CH) (&EVSYS_CH0CTRL)[CH]
void channel_overflow(int i) {
if (IN_PIN(channel[i].dir_pin)) channel[i].high--;
else channel[i].high++;
channel[i].reading = false;
}
ISR(TCC0_OVF_vect) {channel_overflow(0);}
ISR(TCD0_OVF_vect) {channel_overflow(1);}
ISR(TCE0_OVF_vect) {channel_overflow(2);}
ISR(TCF0_OVF_vect) {channel_overflow(3);}
void channel_update_dir(int i) {
if (IN_PIN(channel[i].dir_pin)) channel[i].timer->CTRLFSET = TC0_DIR_bm;
else channel[i].timer->CTRLFCLR = TC0_DIR_bm;
}
ISR(PORTE_INT0_vect) {for (int i = 0; i < 4; i++) channel_update_dir(i);}
int32_t __attribute__ ((noinline)) _channel_read(int i) {
return (int32_t)channel[i].high << 16 | channel[i].timer->CNT;
}
int32_t channel_read(int i) {
while (true) {
channel[i].reading = true;
int32_t x = _channel_read(i);
int32_t y = _channel_read(i);
if (x != y || !channel[i].reading) continue;
channel[i].reading = false;
return x;
}
}
void channel_update_enable(int i) {
if (IN_PIN(MOTOR_ENABLE_PIN))
channel[i].timer->CTRLA = TC_CLKSEL_EVCH0_gc + i;
else channel[i].timer->CTRLA = 0;
}
ISR(PORTF_INT0_vect) {
for (int i = 0; i < 4; i++) channel_update_enable(i);
if (!IN_PIN(MOTOR_ENABLE_PIN)) reset = 2;
}
ISR(PORTC_INT0_vect) {reset = 32;}
ISR(TCC1_OVF_vect) {
if (reset) reset--;
// Report measured steps
static int32_t counts[4] = {0, 0, 0, 0};
bool moving = false;
bool zero = true;
for (int i = 0; i < 4; i++) {
int32_t count = channel_read(i);
if (count != counts[i]) moving = true;
if (count) zero = false;
counts[i] = count;
}
if (reset && !zero) {
for (int i = 0; i < 4; i++) channel_reset(i);
printf("RESET\n");
return;
}
if (moving)
printf("%ld,%ld,%ld,%ld\n", counts[0], counts[1], counts[2], counts[3]);
}
static void _splash(uint8_t addr) {
lcd_init(addr);
lcd_goto(addr, 5, 1);
lcd_pgmstr(addr, PSTR("Step Test"));
}
void channel_init(int i) {
uint8_t step_pin = channel[i].step_pin;
uint8_t dir_pin = channel[i].dir_pin;
// Configure I/O
DIRCLR_PIN(step_pin);
DIRCLR_PIN(dir_pin);
PINCTRL_PIN(step_pin) = PORT_SRLEN_bm | PORT_ISC_RISING_gc;
PINCTRL_PIN(dir_pin) = PORT_SRLEN_bm | PORT_ISC_BOTHEDGES_gc;
// Dir change interrupt
PIN_PORT(dir_pin)->INTCTRL |= PORT_INT0LVL_HI_gc;
PIN_PORT(dir_pin)->INT0MASK |= PIN_BM(dir_pin);
// Events
EVSYS_CHMUX(i) = PIN_EVSYS_CHMUX(step_pin);
EVSYS_CHCTRL(i) = EVSYS_DIGFILT_8SAMPLES_gc;
// Clock
channel_update_enable(i);
channel[i].timer->INTCTRLA = TC_OVFINTLVL_HI_gc;
// Set initial clock direction
channel_update_dir(i);
}
static void init() {
cli();
hw_init();
usart_init();
// Motor channels
for (int i = 0; i < 4; i++) channel_init(i);
// Motor enable
DIRCLR_PIN(MOTOR_ENABLE_PIN);
PINCTRL_PIN(MOTOR_ENABLE_PIN) =
PORT_SRLEN_bm | PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
PIN_PORT(MOTOR_ENABLE_PIN)->INTCTRL |= PORT_INT0LVL_HI_gc;
PIN_PORT(MOTOR_ENABLE_PIN)->INT0MASK |= PIN_BM(MOTOR_ENABLE_PIN);
// Configure report clock
TCC1.INTCTRLA = TC_OVFINTLVL_LO_gc;
TCC1.PER = F_CPU / 256 * 0.01; // 10ms
TCC1.CTRLA = TC_CLKSEL_DIV256_gc;
// Reset switch
DIRCLR_PIN(RESET_PIN);
PINCTRL_PIN(RESET_PIN) =
PORT_SRLEN_bm | PORT_ISC_RISING_gc | PORT_OPC_PULLUP_gc;
PIN_PORT(RESET_PIN)->INTCTRL |= PORT_INT0LVL_LO_gc;
PIN_PORT(RESET_PIN)->INT0MASK |= PIN_BM(RESET_PIN);
printf("RESET\n");
sei();
}
int main() {
init();
_splash(0x27);
_splash(0x3f);
while (true) continue;
return 0;
}

View File

@@ -31,7 +31,6 @@ class Ctrl(object):
self.avr = bbctrl.AVR(self)
self.i2c = bbctrl.I2C(args.i2c_port, args.demo)
self.lcd = bbctrl.LCD(self)
self.mach = bbctrl.Mach(self, self.avr)
self.preplanner = bbctrl.Preplanner(self)
if not args.demo:
@@ -40,9 +39,6 @@ class Ctrl(object):
self.mach.connect()
self.lcd.add_new_page(bbctrl.MainLCDPage(self))
self.lcd.add_new_page(bbctrl.IPLCDPage(self.lcd))
os.environ['GCODE_SCRIPT_PATH'] = self.get_upload()
except Exception:

View File

@@ -1,48 +0,0 @@
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import subprocess
import bbctrl
class IPLCDPage(bbctrl.LCDPage):
# From bbctrl.LCDPage
def activate(self):
p = subprocess.Popen(['hostname', '-I'], stdout = subprocess.PIPE)
ips = p.communicate()[0].decode('utf-8').split()
p = subprocess.Popen(['hostname'], stdout = subprocess.PIPE)
hostname = p.communicate()[0].decode('utf-8').strip()
self.clear()
self.text('Host: %s' % hostname[0:14], 0, 0)
for i in range(min(3, len(ips))):
if len(ips[i]) <= 16:
self.text('IP: %s' % ips[i], 0, i + 1)

View File

@@ -64,12 +64,6 @@ class Jog(inevent.JogHandler):
self.processor = inevent.InEvent(ctrl.ioloop, self, types = ['js'])
def up(self): self.ctrl.lcd.page_up()
def down(self): self.ctrl.lcd.page_down()
def left(self): self.ctrl.lcd.page_left()
def right(self): self.ctrl.lcd.page_right()
def callback(self):
if self.v != self.lastV:
self.lastV = self.v

View File

@@ -1,207 +0,0 @@
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import lcd
import atexit
class LCDPage:
def __init__(self, lcd, text = None):
self.lcd = lcd
self.data = lcd.new_screen()
if text is not None:
self.text(text, (lcd.width - len(text)) // 2, 1)
def activate(self): pass
def deactivate(self): pass
def put(self, c, x, y):
y += x // self.lcd.width
x %= self.lcd.width
y %= self.lcd.height
if self.data[x][y] != c:
self.data[x][y] = c
if self == self.lcd.page: self.lcd.update()
def text(self, s, x, y):
for c in s:
self.put(c, x, y)
x += 1
def clear(self):
self.data = self.lcd.new_screen()
self.lcd.redraw = True
def shift_left(self): pass
def shift_right(self): pass
def shift_up(self): pass
def shift_down(self): pass
class LCD:
def __init__(self, ctrl):
self.ctrl = ctrl
self.log = ctrl.log.get('LCD')
self.addrs = self.ctrl.args.lcd_addr
self.addr = self.addrs[0]
self.addr_num = 0
self.width = 20
self.height = 4
self.lcd = None
self.timeout = None
self.reset = False
self.page = None
self.pages = []
self.current_page = 0
self.screen = self.new_screen()
self.set_message('Loading...')
self._redraw(False)
if not ctrl.args.demo: atexit.register(self.goodbye)
def set_message(self, msg):
try:
self.load_page(LCDPage(self, msg))
self._update()
except IOError as e:
self.log.warning('LCD communication failed: %s' % e)
def new_screen(self):
return [[' ' for y in range(self.height)] for x in range(self.width)]
def new_page(self): return LCDPage(self)
def add_page(self, page): self.pages.append(page)
def add_new_page(self, page = None):
if page is None: page = self.new_page()
page.id = len(self.pages)
self.add_page(page)
return page
def load_page(self, page):
if self.page != page:
if self.page is not None: self.page.deactivate()
page.activate()
self.page = page
self.redraw = True
self.update()
def set_current_page(self, current_page):
self.current_page = current_page % len(self.pages)
self.load_page(self.pages[self.current_page])
def page_up(self): pass
def page_down(self): pass
def page_right(self): self.set_current_page(self.current_page + 1)
def page_left(self): self.set_current_page(self.current_page - 1)
def update(self):
if self.timeout is None:
self.timeout = self.ctrl.ioloop.call_later(0.25, self._update)
def _redraw(self, now = True):
if now:
self.redraw = True
self.update()
self.redraw_timer = self.ctrl.ioloop.call_later(5, self._redraw)
def _update(self):
self.timeout = None
try:
if self.lcd is None:
self.lcd = lcd.LCD(self.ctrl.i2c, self.addr, self.height,
self.width)
if self.reset:
self.lcd.reset()
self.redraw = True
self.reset = False
cursorX, cursorY = -1, -1
for y in range(self.height):
for x in range(self.width):
c = self.page.data[x][y]
if self.redraw or self.screen[x][y] != c:
if cursorX != x or cursorY != y:
self.lcd.goto(x, y)
cursorX, cursorY = x, y
self.lcd.put_char(c)
cursorX += 1
self.screen[x][y] = c
self.redraw = False
except IOError as e:
# Try next address
#self.addr_num += 1
#if len(self.addrs) <= self.addr_num: self.addr_num = 0
#self.addr = self.addrs[self.addr_num]
#self.lcd = None
#self.log.warning('LCD communication failed, ' +
# 'retrying on address 0x%02x: %s' % (self.addr, e))
#self.log.warning('LCD not present.')
#self.reset = True
self.reset = False
#self.timeout = self.ctrl.ioloop.call_later(1, self._update)
def goodbye(self, message = ''):
if self.timeout:
self.ctrl.ioloop.remove_timeout(self.timeout)
self.timeout = None
if self.redraw_timer:
self.ctrl.ioloop.remove_timeout(self.redraw_timer)
self.redraw_timer = None
if self.lcd is not None: self.set_message(message)

View File

@@ -1,76 +0,0 @@
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import bbctrl
class MainLCDPage(bbctrl.LCDPage):
def __init__(self, ctrl):
bbctrl.LCDPage.__init__(self, ctrl.lcd)
self.ctrl = ctrl
self.install = True
ctrl.state.add_listener(self.update)
def update(self, update):
state = self.ctrl.state
# Must be after machine vars have loaded
if self.install and hasattr(self, 'id'):
self.install = False
self.ctrl.lcd.set_current_page(self.id)
self.text('%-9s' % state.get('xx', ''), 0, 0)
metric = not state.get('imperial', False)
scale = 1 if metric else 25.4
# Show enabled axes
row = 0
for axis in 'xyzabc':
if state.is_axis_faulted(axis):
self.text(' FAULT %s' % axis.upper(), 9, row)
row += 1
elif state.is_axis_enabled(axis):
position = state.get(axis + 'p', 0)
position += state.get('offset_' + axis, 0)
position /= scale
self.text('% 10.3f%s' % (position, axis.upper()), 9, row)
row += 1
while row < 4:
self.text(' ' * 11, 9, row)
row += 1
# Show tool, units, feed and speed
self.text('%2uT' % state.get('tool', 0), 6, 1)
self.text('%-6s' % 'MM' if metric else 'INCH', 0, 1)
self.text('%8uF' % (state.get('feed', 0) / scale), 0, 2)
self.text('%8dS' % state.get('speed', 0), 0, 3)

View File

@@ -68,7 +68,6 @@ class Pwr():
self.i2c_addr = ctrl.args.pwr_addr
self.regs = [-1] * 9
self.lcd_page = ctrl.lcd.add_new_page()
self.failures = 0
self._update_cb(False)
@@ -179,16 +178,6 @@ class Pwr():
self.failures = 0
return
self.lcd_page.text('%3dC Tmp' % self.regs[TEMP_REG], 0, 0)
self.lcd_page.text('%5.1fV In' % self.regs[VIN_REG], 0, 1)
self.lcd_page.text('%5.1fV Out' % self.regs[VOUT_REG], 0, 2)
self.lcd_page.text(' %04x Flg' % self.regs[FLAGS_REG], 0, 3)
self.lcd_page.text('%5.1fA Mot' % self.regs[MOTOR_REG], 10, 0)
self.lcd_page.text('%5.1fA Ld1' % self.regs[LOAD1_REG], 10, 1)
self.lcd_page.text('%5.1fA Ld2' % self.regs[LOAD2_REG], 10, 2)
self.lcd_page.text('%5.1fA Vdd' % self.regs[VDD_REG], 10, 3)
if len(update): self.ctrl.state.update(update)
self.failures = 0

View File

@@ -22,7 +22,6 @@ def call_get_output(cmd):
class RebootHandler(bbctrl.APIHandler):
def put_ok(self):
self.get_ctrl().lcd.goodbye('Rebooting...')
subprocess.Popen('reboot')
@@ -193,13 +192,11 @@ class FirmwareUpdateHandler(bbctrl.APIHandler):
with open('firmware/update.tar.bz2', 'wb') as f:
f.write(firmware['body'])
self.get_ctrl().lcd.goodbye('Upgrading firmware')
subprocess.Popen(['/usr/local/bin/update-bbctrl'])
class UpgradeHandler(bbctrl.APIHandler):
def put_ok(self):
self.get_ctrl().lcd.goodbye('Upgrading firmware')
subprocess.Popen(['/usr/local/bin/upgrade-bbctrl'])

View File

@@ -40,7 +40,6 @@ from bbctrl.RequestHandler import RequestHandler
from bbctrl.APIHandler import APIHandler
from bbctrl.FileHandler import FileHandler
from bbctrl.Config import Config
from bbctrl.LCD import LCD, LCDPage
from bbctrl.Mach import Mach
from bbctrl.Web import Web
from bbctrl.Jog import Jog
@@ -52,8 +51,6 @@ from bbctrl.Preplanner import Preplanner
from bbctrl.State import State
from bbctrl.Comm import Comm
from bbctrl.CommandQueue import CommandQueue
from bbctrl.MainLCDPage import MainLCDPage
from bbctrl.IPLCDPage import IPLCDPage
from bbctrl.Camera import Camera, VideoHandler
from bbctrl.AVR import AVR
from bbctrl.AVREmu import AVREmu
@@ -132,8 +129,6 @@ def parse_args():
help = 'Serial baud rate')
parser.add_argument('--i2c-port', default = 1, type = int,
help = 'I2C port')
parser.add_argument('--lcd-addr', default = [0x27, 0x3f], type = int,
help = 'LCD I2C address')
parser.add_argument('--avr-addr', default = 0x2b, type = int,
help = 'AVR I2C address')
parser.add_argument('--pwr-addr', default = 0x60, type = int,

View File

@@ -72,12 +72,6 @@ class JogHandler:
log.info(axes_to_string(self.axes) + ' x {:d}'.format(self.speed))
def up(self): log.debug('up')
def down(self): log.debug('down')
def left(self): log.debug('left')
def right(self): log.debug('right')
def reset(self):
self.axes = [0.0, 0.0, 0.0, 0.0]
self.speed = 3
@@ -105,17 +99,6 @@ class JogHandler:
if event.type == EV_ABS and event.code in config['axes']:
pass
elif event.type == EV_ABS and event.code in config['arrows']:
axis = config['arrows'].index(event.code)
if event.value < 0:
if axis == 1: self.up()
else: self.left()
elif 0 < event.value:
if axis == 1: self.down()
else: self.right()
elif event.type == EV_KEY and event.code in config['speed']:
old_speed = self.speed
self.speed = config['speed'].index(event.code) + 1

View File

@@ -1,236 +0,0 @@
#!/usr/bin/env python3
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import time
import logging
log = logging.getLogger('LCD')
# Control flags
REG_SELECT_BIT = 1 << 0
READ_BIT = 1 << 1
ENABLE_BIT = 1 << 2
BACKLIGHT_BIT = 1 << 3
# Commands
LCD_CLEAR_DISPLAY = 1 << 0
LCD_RETURN_HOME = 1 << 1
LCD_ENTRY_MODE_SET = 1 << 2
LCD_DISPLAY_CONTROL = 1 << 3
LCD_CURSOR_SHIFT = 1 << 4
LCD_FUNCTION_SET = 1 << 5
LCD_SET_CGRAM_ADDR = 1 << 6
LCD_SET_DDRAM_ADDR = 1 << 7
# Entry Mode Set flags
LCD_ENTRY_SHIFT_DISPLAY = 1 << 0
LCD_ENTRY_SHIFT_INC = 1 << 1
LCD_ENTRY_SHIFT_DEC = 0 << 1
# Display Control flags
LCD_BLINK_ON = 1 << 0
LCD_BLINK_OFF = 0 << 0
LCD_CURSOR_ON = 1 << 1
LCD_CURSOR_OFF = 0 << 1
LCD_DISPLAY_ON = 1 << 2
LCD_DISPLAY_OFF = 0 << 2
# Cursor Shift flags
LCD_SHIFT_RIGHT = 1 << 2
LCD_SHIFT_LEFT = 0 << 2
LCD_SHIFT_DISPLAY = 1 << 3
LCD_SHIFT_CURSOR = 0 << 3
# Function Set flags
LCD_5x11_DOTS = 1 << 2
LCD_5x8_DOTS = 0 << 2
LCD_2_LINE = 1 << 3
LCD_1_LINE = 0 << 3
LCD_8_BIT_MODE = 1 << 4
LCD_4_BIT_MODE = 0 << 4
# Text justification flags
JUSTIFY_LEFT = 0
JUSTIFY_RIGHT = 1
JUSTIFY_CENTER = 2
class LCD:
def __init__(self, i2c, addr, height = 4, width = 20):
self.addr = addr
self.height = height
self.width = width
self.i2c = i2c
self.backlight = True
self.reset()
def reset(self):
self.clear()
time.sleep(0.050)
self.write_nibble(3 << 4) # Home
time.sleep(0.050)
self.write_nibble(3 << 4) # Home
time.sleep(0.050)
self.write_nibble(3 << 4) # Home
self.write_nibble(2 << 4) # 4-bit
self.write(LCD_FUNCTION_SET | LCD_2_LINE | LCD_5x8_DOTS |
LCD_4_BIT_MODE)
self.write(LCD_DISPLAY_CONTROL | LCD_DISPLAY_ON)
self.write(LCD_ENTRY_MODE_SET | LCD_ENTRY_SHIFT_INC)
def write_i2c(self, data):
if self.backlight: data |= BACKLIGHT_BIT
self.i2c.write(self.addr, data)
time.sleep(0.0001)
# Write half of a command to LCD
def write_nibble(self, data):
self.write_i2c(data)
# Strobe
self.write_i2c(data | ENABLE_BIT)
time.sleep(0.0005)
self.write_i2c(data & ~ENABLE_BIT)
time.sleep(0.0001)
# Write an 8-bit command to LCD
def write(self, cmd, flags = 0):
self.write_nibble(flags | (cmd & 0xf0))
self.write_nibble(flags | ((cmd << 4) & 0xf0))
def set_cursor(self, on, blink):
data = LCD_DISPLAY_CONTROL
if on: data |= LCD_CURSOR_ON
if blink: data |= LCD_BLINK_ON
self.write(data)
def set_backlight(self, enable):
self.backlight = enable
self.write_i2c(0)
def program_char(self, addr, data):
if addr < 0 or 8 <= addr: return
self.write(LCD_SET_CGRAM_ADDR | (addr << 3))
for x in data:
self.write(x, REG_SELECT_BIT)
def goto(self, x, y):
if x < 0 or self.width <= x or y < 0 or self.height <= y: return
self.write(LCD_SET_DDRAM_ADDR | (0, 64, 20, 84)[y] + int(x))
def put_char(self, c):
self.write(ord(c), REG_SELECT_BIT)
def text(self, msg, x = None, y = None):
if x is not None and y is not None: self.goto(x, y)
for c in msg: self.put_char(c)
def display(self, line, msg, justify = JUSTIFY_LEFT):
if justify == JUSTIFY_RIGHT: x = self.width - len(msg)
elif justify == JUSTIFY_CENTER: x = (self.width - len(msg)) / 2
else: x = 0
if x < 0: x = 0
self.text(msg, x, line)
def shift(self, count = 1, right = True, display = True):
cmd = LCD_CURSOR_SHIFT
if right: cmd |= LCD_SHIFT_RIGHT
if display: cmd |= LCD_SHIFT_DISPLAY
for i in range(count): self.write(cmd)
# Clear LCD and move cursor home
def clear(self):
self.write(LCD_CLEAR_DISPLAY)
self.write(LCD_RETURN_HOME)
if __name__ == "__main__":
lcd = LCD(1, 0x27)
lcd.clear()
lcd.program_char(0, (0b11011,
0b11011,
0b00000,
0b01100,
0b01100,
0b00000,
0b11011,
0b11011))
lcd.program_char(1, (0b11000,
0b01100,
0b00110,
0b00011,
0b00011,
0b00110,
0b01100,
0b11000))
lcd.program_char(2, (0b00011,
0b00110,
0b01100,
0b11000,
0b11000,
0b01100,
0b00110,
0b00011))
lcd.display(0, '\0' * lcd.width)
lcd.display(1, 'Hello world!', JUSTIFY_CENTER)
lcd.display(2, '\1\2' * (lcd.width / 2))
lcd.display(3, '12345678901234567890')

View File

@@ -1,38 +0,0 @@
#!/usr/bin/env python3
################################################################################
# #
# This file is part of the Buildbotics firmware. #
# #
# Copyright (c) 2015 - 2018, Buildbotics LLC #
# All rights reserved. #
# #
# This file ("the software") is free software: you can redistribute it #
# and/or modify it under the terms of the GNU General Public License, #
# version 2 as published by the Free Software Foundation. You should #
# have received a copy of the GNU General Public License, version 2 #
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
# #
# The software is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
# Lesser General Public License for more details. #
# #
# You should have received a copy of the GNU Lesser General Public #
# License along with the software. If not, see #
# <http://www.gnu.org/licenses/>. #
# #
# For information regarding this software email: #
# "Joseph Coffland" <joseph@buildbotics.com> #
# #
################################################################################
import lcd
if __name__ == "__main__":
screen = lcd.LCD(1, 0x27)
screen.clear()
screen.display(0, 'Buildbotics', lcd.JUSTIFY_CENTER)
screen.display(1, 'Controller', lcd.JUSTIFY_CENTER)
screen.display(3, 'Booting...', lcd.JUSTIFY_CENTER)