//--------------------------------------------------------- // VelociBus Breadboard Example // 2022.06.06 RSP // Target: Arduino Pro Mini 5V/16MHz // Demonstrates VelociBus modules //--------------------------------------------------------- // using I2C-USART bridge for 2'nd serial port #include "FEARLESS_Serial_I2C_Bridge.h" SerialI2Cbridge i2cSerial; // create a serial bridge // VelociBus interface functions #include "FEARLESS_VelociBus.h" VelociBus vbus; // create a VelociBus handler // VelociBus module configuration #define NUM_MODULES 6 // number of modules in VelociBus chain #define VBUTTONS_ADDR 0 #define VGESTURE_ADDR 1 #define VROTOR_ADDR 2 #define VROTOR9V_ADDR 3 #define VROTOR9H_ADDR 4 #define VRECEIVER_ADDR 5 // the module addresses reverse based on the direction of data travel #define RX(addr) (addr) // module address to use when receiving data #define TX(addr) (NUM_MODULES-addr-1) // module address to use when sending data //--------------------------------------------------------- void setup() { Wire.begin(); Wire.setClock(400000); // high speed why not // diagnostics on serial monitor Serial.begin(115200); Serial.println(F("STARTUP")); // bridge serial VelociBus to I2C i2cSerial.begin(); // defaults to I2C address 8, ready pin 2 vbus.begin( &i2cSerial ); delay(500); // velociGesture needs time to boot up // benign but slow chain test Serial.print(F("CHAIN LENGTH = ")); Serial.println(vbus.chainLength()); // quicker test with possible side effects Serial.print(F("COMMAND CHAIN LENGTH = ")); Serial.println(vbus.commandChainLength()); // set proximity mode, enable exit events vbus.gestureProximity( TX(VGESTURE_ADDR), 2, true, false ); // set neopixel brightness max (3), enable release & long press button events vbus.buttonConfig( TX(VBUTTONS_ADDR), 3, true, true ); // inverted VelociRotor9V vbus.rotor9setBrightness( TX(VROTOR9V_ADDR), 2, true ); } //--------------------------------------------------------- // VelociButtons module button event handler void buttonHandler(int8_t address, uint8_t button_index, VelociBus::BUTTON_EVENT event) { if (event == VelociBus::press) // turn on or off LEDs depending on which button is hit { for (uint8_t i=1; i <= 5; i++) vbus.buttonOutput( TX(VBUTTONS_ADDR), i, button_index == 15 ); for (uint8_t i=0; i < 8; i++) vbus.buttonPixel( TX(VBUTTONS_ADDR), i, button_index != 15 ? random(1,32) : 0 ); } } // VelociGesture module proximity event handler void proximityHandler(int8_t address, VelociBus::PROXIMITY_EVENT event ) { uint8_t c = 0; switch (event) // turn on LEDs if near, turn off LEDs if proximity exit { case VelociBus::near: case VelociBus::far: c = 2; break; // red case VelociBus::exit: c = 0; // black } for (uint8_t i=0; i < 8; i++) vbus.buttonPixel( TX(VBUTTONS_ADDR), i, c ); } //--------------------------------------------------------- void loop() { // receive & decode VelociBus events vbus_packet pkt; if (vbus.poll( &pkt )) { Serial.print("PKT "); Serial.print(pkt.address,HEX); Serial.print(", "); Serial.println(pkt.data,HEX); switch (pkt.address) { case RX(VBUTTONS_ADDR): // turn the LEDs on/off // VelociButtons module vbus.buttonDecode( pkt, buttonHandler ); // calls buttonHandler if a button event is detected break; case RX(VROTOR_ADDR): // spin the LED color // VelociRorot module { static uint8_t color = 0; int8_t spin = vbus.rotorDecodeSpin( pkt ); // get knob motion since last reading if (spin) { color = (color+32+(spin > 0 ? 1:-1)) % 32; // knob spins the LED color vbus.rotorLED( TX(VROTOR_ADDR), color ); } } break; case RX(VROTOR9V_ADDR): // spin the 7-segment display // VelociRotor9V module { static uint16_t value = 0; int8_t spin = vbus.rotorDecodeSpin( pkt ); // get knob motion since last reading if (spin) { value = (value+16+(spin > 0 ? 1:-1)) % 16; // knob spins the displayed number vbus.rotor9LED( TX(VROTOR9V_ADDR), value ); } } break; case RX(VROTOR9H_ADDR): // spin the 7-segment display // VelociRotor9H module { static uint16_t value = 0; int8_t spin = vbus.rotorDecodeSpin( pkt ); // get knob motion since last reading if (spin) { value = (value+16+(spin > 0 ? 1:-1)) % 16; // knob spins the displayed number vbus.rotor9LED( TX(VROTOR9H_ADDR), value ); } } break; case RX(VRECEIVER_ADDR): // VelociReceiver module // pkt.data is the IR remote button index vbus.rotor9LED( TX(VROTOR9H_ADDR), pkt.data & 0x0F ); // show (truncated) index on VelociRotor9 numeric LED break; case RX(VGESTURE_ADDR): // VelociGesture module vbus.proximityDecode( pkt, proximityHandler ); // calls proximityHandler if a proximity event is detected } } }