diff --git a/setup.py b/setup.py
index e3bd034..8e7dbdf 100755
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,6 @@ setup(
packages=[
'bbctrl',
'inevent',
- 'lcd',
'camotics',
'iw_parse'
],
diff --git a/src/avr/src/lcd.c b/src/avr/src/lcd.c
deleted file mode 100644
index 7802eb4..0000000
--- a/src/avr/src/lcd.c
+++ /dev/null
@@ -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 .
-
- 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
- .
-
- For information regarding this software email:
- "Joseph Coffland"
-
-\******************************************************************************/
-
-#include "lcd.h"
-#include "rtc.h"
-#include "hardware.h"
-#include "command.h"
-
-#include
-#include
-#include
-
-#include
-
-
-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();
-}
diff --git a/src/avr/src/lcd.h b/src/avr/src/lcd.h
deleted file mode 100644
index b7369f0..0000000
--- a/src/avr/src/lcd.h
+++ /dev/null
@@ -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 .
-
- 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
- .
-
- For information regarding this software email:
- "Joseph Coffland"
-
-\******************************************************************************/
-
-#pragma once
-
-#include "pgmspace.h"
-
-#include
-
-
-// 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();
diff --git a/src/avr/src/rtc.c b/src/avr/src/rtc.c
index 8020895..f52c4fc 100644
--- a/src/avr/src/rtc.c
+++ b/src/avr/src/rtc.c
@@ -30,7 +30,6 @@
#include "switch.h"
#include "analog.h"
#include "motor.h"
-#include "lcd.h"
#include "vfd_spindle.h"
#include
@@ -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();
diff --git a/src/avr/step-test/Makefile b/src/avr/step-test/Makefile
deleted file mode 100644
index 52f894a..0000000
--- a/src/avr/step-test/Makefile
+++ /dev/null
@@ -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
diff --git a/src/avr/step-test/plot_velocity.py b/src/avr/step-test/plot_velocity.py
deleted file mode 100644
index 2006faf..0000000
--- a/src/avr/step-test/plot_velocity.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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()
diff --git a/src/avr/step-test/step-test.c b/src/avr/step-test/step-test.c
deleted file mode 100644
index db267bf..0000000
--- a/src/avr/step-test/step-test.c
+++ /dev/null
@@ -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 .
-
- 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
- .
-
- For information regarding this software email:
- "Joseph Coffland"
-
-\******************************************************************************/
-
-#include "config.h"
-#include "hardware.h"
-#include "usart.h"
-#include "lcd.h"
-
-#include
-
-#include
-#include
-
-
-#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;
-}
diff --git a/src/py/bbctrl/Ctrl.py b/src/py/bbctrl/Ctrl.py
index 43fa61f..fae382c 100644
--- a/src/py/bbctrl/Ctrl.py
+++ b/src/py/bbctrl/Ctrl.py
@@ -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:
diff --git a/src/py/bbctrl/IPLCDPage.py b/src/py/bbctrl/IPLCDPage.py
deleted file mode 100644
index 4f5ee4e..0000000
--- a/src/py/bbctrl/IPLCDPage.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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)
diff --git a/src/py/bbctrl/Jog.py b/src/py/bbctrl/Jog.py
index c4544e2..f198bdf 100644
--- a/src/py/bbctrl/Jog.py
+++ b/src/py/bbctrl/Jog.py
@@ -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
diff --git a/src/py/bbctrl/LCD.py b/src/py/bbctrl/LCD.py
deleted file mode 100644
index 38f6adb..0000000
--- a/src/py/bbctrl/LCD.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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)
diff --git a/src/py/bbctrl/MainLCDPage.py b/src/py/bbctrl/MainLCDPage.py
deleted file mode 100644
index ba17391..0000000
--- a/src/py/bbctrl/MainLCDPage.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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)
diff --git a/src/py/bbctrl/Pwr.py b/src/py/bbctrl/Pwr.py
index 9c4579a..32b46c6 100644
--- a/src/py/bbctrl/Pwr.py
+++ b/src/py/bbctrl/Pwr.py
@@ -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
diff --git a/src/py/bbctrl/Web.py b/src/py/bbctrl/Web.py
index 148fcdd..1a96146 100644
--- a/src/py/bbctrl/Web.py
+++ b/src/py/bbctrl/Web.py
@@ -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'])
diff --git a/src/py/bbctrl/__init__.py b/src/py/bbctrl/__init__.py
index b1a6452..c5cae69 100644
--- a/src/py/bbctrl/__init__.py
+++ b/src/py/bbctrl/__init__.py
@@ -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,
diff --git a/src/py/inevent/JogHandler.py b/src/py/inevent/JogHandler.py
index f5fad5b..f03c5a8 100644
--- a/src/py/inevent/JogHandler.py
+++ b/src/py/inevent/JogHandler.py
@@ -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
diff --git a/src/py/lcd/__init__.py b/src/py/lcd/__init__.py
deleted file mode 100644
index 238a6e1..0000000
--- a/src/py/lcd/__init__.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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')
diff --git a/src/py/lcd/splash.py b/src/py/lcd/splash.py
deleted file mode 100644
index 203f60a..0000000
--- a/src/py/lcd/splash.py
+++ /dev/null
@@ -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 . #
-# #
-# 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 #
-# . #
-# #
-# For information regarding this software email: #
-# "Joseph Coffland" #
-# #
-################################################################################
-
-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)