diff --git a/firmware/TouchwheelSAO_attiny816/TouchwheelSAO_attiny816.ino b/firmware/TouchwheelSAO_attiny816/TouchwheelSAO_attiny816.ino index a7c2569..72d4248 100644 --- a/firmware/TouchwheelSAO_attiny816/TouchwheelSAO_attiny816.ino +++ b/firmware/TouchwheelSAO_attiny816/TouchwheelSAO_attiny816.ino @@ -22,6 +22,7 @@ // using seesaw's neopixel driver instead of megatinycore's tinyneopixel // because it saves 500 bytes of flash // but seems to glitch out, so going back to tinyNeoPixel_Static for now +// update: ahh seems like tinyNeoPixel_Static calls `noInterrupts()` so we'll mirror that #define MY_I2C_ADDR 0x54 #define FPOS_FILT (0.05) @@ -145,12 +146,19 @@ void setup() { pinMode(NEOPIXEL_PIN, OUTPUT); // do a little fade up to indicate we're alive - for( int i=0; i<100; i++) { + for(byte i=0; i<100; i++) { ledr = i, ledg = i, ledb = i; pixel_fill(ledr, ledg, ledb); pixel_show(); delay(10); } + for(byte i=0; i<255; i++) { + uint32_t c = wheel(i); + uint8_t r = (c>>16) & 0xff, g = (c>>8) & 0xff, b = c&0xff; + pixel_fill(r,g,b); + pixel_show(); + delay(5); + } // Touch buttons for (int i = 0; i < touch_count; i++) { @@ -165,7 +173,7 @@ void setup() { uint32_t last_debug_time; uint32_t last_led_time; -uint8_t pos = 0; +int pos = 0; uint8_t touch_timer = 255; // main loop @@ -178,10 +186,13 @@ void loop() { // simple iir filtering on touch inputs float fpos = wheel_pos(); - const float filt = FPOS_FILT; // 0.05; - if(fpos > -1) { // fpos ranges 0-1, -1 == no touch + const float filt = FPOS_FILT; + if(touched) { // fpos ranges 0-1, -1 == no touch fpos = (fpos * 255); - pos = filt * fpos + (1-filt) * pos; + //pos = filt * fpos + (1-filt) * pos; + pos = fpos; + touch_timer = min(touch_timer+10, 255); + if( pos < 10 ) { pos = 1; } // hack } else { pos = 0; @@ -230,24 +241,12 @@ void loop() { // if touched, light up if( touched ) { - touch_timer = 255; - //ledr = 50, ledg = 50, ledb = 50; // turn right dim white - - uint32_t c = Wheel(pos); - // sigh - ledr = (c>>16) & 0xff; - ledg = (c>>8) & 0xff; - ledb = (c>>0) & 0xff; - - // if( pos < 85 ) { - // pixel_set(1, 100+pos, 100+pos, ledb); - // } - // else if( pos < 170 ) { - // pixel_set(2, 100+(pos-85), 100+(pos-85), ledb); - // } - // else { - // pixel_set(0, 100+(pos-170), 100+(pos-85), ledb); - // } + //touch_timer = 255; + uint32_t c = wheel(pos); + // sigh, unpack: fixme: change wheel to take r,g,b ptrs + ledr = (c>>16) & 0xff; + ledg = (c>>8) & 0xff; + ledb = (c>>0) & 0xff; } pixel_show(); } @@ -256,7 +255,7 @@ void loop() { if( now - last_debug_time > 50 ) { last_debug_time = now; // leds_fill( ) - MySerial.printf("pos: %d\r\n", pos); + MySerial.printf("pos: %d %d\r\n", pos, touch_timer); } // delay(1); @@ -294,7 +293,7 @@ static uint32_t pack_color(uint8_t r, uint8_t g, uint8_t b) { // Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. -uint32_t Wheel(byte WheelPos) { +uint32_t wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if (WheelPos < 85) { return pack_color(255 - WheelPos * 3, 0, WheelPos * 3); diff --git a/firmware/tester/code_display.py b/firmware/tester/code_display.py new file mode 100644 index 0000000..fdba5b3 --- /dev/null +++ b/firmware/tester/code_display.py @@ -0,0 +1,118 @@ +# touchwheelsao_tester.py -- simple I2C host for TouchWheelSAO +# 5 Aug 2024 - @todbot / Tod Kurt +# + + +import time, board, busio +import displayio, terminalio, i2cdisplaybus +import adafruit_displayio_ssd1306 +from adafruit_display_text import bitmap_label as label +from adafruit_bus_device import i2c_device + +sao_i2c_addr = 0x54 + +sao_i2c = busio.I2C(scl=board.GP17, sda=board.GP16) +sao_i2cdev = None + +dw,dh = 128,64 +displayio.release_displays() +disp_i2c = busio.I2C(scl=board.GP15, sda=board.GP14) +display_bus = i2cdisplaybus.I2CDisplayBus(disp_i2c, device_address=0x3C) # or 0x3D depending on display +display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=dw, height=dh, rotation=180) +maingroup = displayio.Group() +display.root_group = maingroup +lbl_title = label.Label(terminalio.FONT, text="TouchwheelSAO tester", x=0, y=10, scale=1) +lbl_pos_text = label.Label(terminalio.FONT, text="pos:", x=0, y=30, scale=1) +lbl_pos_val = label.Label(terminalio.FONT, text="unk", x=30, y=30, scale=1) +lbl_touches_text = label.Label(terminalio.FONT, text="touches:", x=0, y=50, scale=1) +lbl_touches_val = label.Label(terminalio.FONT, text=" ", x=60, y=50, scale=1) +for l in (lbl_title, lbl_pos_text, lbl_pos_val, lbl_touches_text, lbl_touches_val): + maingroup.append(l) + + +def i2c_scan(i2c): + if i2c is None: return + while not i2c.try_lock(): pass + print("I2C addresses found:", + [hex(device_address) for device_address in i2c.scan()]) + i2c.unlock() + +def i2c_write_register(_i2cdev, reg_addr, reg_val): + """Write 8 bit value to register at address.""" + if _i2cdev is None: return + _buf = bytearray(2) + _buf[0] = reg_addr + _buf[1] = reg_val + with _i2cdev as myi2cdev: + myi2cdev.write(_buf) + +def i2c_read_register_bytes(_i2cdev, reg_addr, num_bytes): + with _i2cdev as myi2cdev: + myi2cdev.write(bytes([reg_addr])) + result = bytearray(num_bytes) + myi2cdev.readinto(result) + return result + +#time.sleep(5) + +led_state = 0 + +i2c_scan(sao_i2c) + +while True: + + if sao_i2cdev is None: + time.sleep(1) + try: + sao_i2cdev = i2c_device.I2CDevice(sao_i2c, sao_i2c_addr) + except ValueError as e: + print("SAO error:", e) + + try: + r = i2c_read_register_bytes(sao_i2cdev, 0, 1) + pos = r[0] + print(" pos:", pos) + + lbl_pos_val.text = str(pos) if pos > 0 else "no touch" + + r = i2c_read_register_bytes(sao_i2cdev, 1, 1) + print(" touches:", r, f'{r[0]:03b}') + lbl_touches_val.text = f'{r[0]:03b}' + + except Exception as e: + print("SAO no device:", e) + lbl_pos_val.text = "no SAO" + sao_i2cdev = None + + time.sleep(0.2) + + + # try: + # print("%.2f write reg:" % time.monotonic()) + # i2c_write_register(sao_i2cdev, 14, led_state) + # led_state = not led_state + # #i2c_write_register(i2cdev, 17, 100) # set RGB B + # print("reading...:") + # r = i2c_read_register_bytes(sao_i2cdev, 0, 1) + # print(" pos:", r, r[0]) + + # lbl_pos_val.text = str(r[0]) + + # r = i2c_read_register_bytes(sao_i2cdev, 1, 1) + # print(" touches:", r, f'{r[0]:03b}') + # r = i2c_read_register_bytes(sao_i2cdev, 2, 1) # RAW0L + # print(" raw0L:", r, r[0]) + # r = i2c_read_register_bytes(sao_i2cdev, 3, 1) # RAW0H + # print(" raw0H:", r, r[0]) + # r = i2c_read_register_bytes(sao_i2cdev, 8, 1) # THRESH0L + # print(" thresh0L:", r, r[0]) + + # except OSError as e: + # print(e) + # time.sleep(0.2) + + + + + +