G+_Jerome Semichon Posted May 23, 2017 Share Posted May 23, 2017 PadreSJ In the last KH, there was a discussion of a RasPi controlling Arduinos - at least 1 way. It's really easy to do using I2C and a logic level shifter. Once you've pushed your SCA and SDA through the logic level shifter, conect them to the right Arduino pins and use the Arduino; give it 5V and ground and voila! The hardest bit is to agree (with yourself) on the "protocol" you will be using (i.e. what bytes / bits mean what when sent in either direction). One of my projects (pond automation and control) uses several Arduino Mini Pro to control LED, several relays, etc. quite nicely. This is also very useful to control WS2812B (lights, shiny lights, everywhere!). The RasPi (1 or 3 in my case) cannot seem to send data at the right rate and sustain that rate to control a string whereas an Arduino has no problem with that. So best of both worlds, use the Pi as the main controller with WiFi, a proper OS, etc. and dish out tasks to 1 or more mini pro. Hopefully this will be useful. This is the code I wrote on the mini pro to control an 8-bit WS2812B string:. The RasPi simply gives it a single byte, the 4 high order bits tell it which LED to change and the 4 low order bits give it a colour. Basic and simple but it does what I want. The code on the RasPi is in C and is part of a much more complex program but the I2C code is very simple to write (sorry, I don't really do Python, I'm old-fashioned :-)). #include #include #include #define I2C_SLAVE_ADDRESS 0x03 #define MAX_UPDATE_GAP 300 #define LED_QTY 8 #define LED_DATA_PIN 2 #define LED_BRIGHTNESS 25 #define LED_COLOUR_ORDER GRB #define LED_TYPE WS2812B #define LED_COLOUR_BLACK 0x00 #define LED_COLOUR_BLUE 0x01 #define LED_COLOUR_GREEN 0x02 #define LED_COLOUR_AMBER 0x03 #define LED_COLOUR_RED 0x04 #define LED_COLOUR_WHITE 0x0f CRGB oLED[LED_QTY]; boolean bDebug = false; time_t tLastUpdate; void setup() { int i; if (bDebug == true) Serial.begin(115200); pinMode(LED_DATA_PIN, OUTPUT); Wire.begin(I2C_SLAVE_ADDRESS); // Set the I2C callback functions Wire.onReceive(receiveI2CData); Wire.onRequest(sendI2CData); FastLED.addLeds(oLED, LED_QTY).setCorrection(TypicalLEDStrip); FastLED.setBrightness(LED_BRIGHTNESS); for (i = 0 ; i < LED_QTY ; i++) oLED = CRGB::Gold; tLastUpdate = now(); Serial.println("Ready!"); } void loop() { short i; time_t tNow = now(); if (tNow > (tLastUpdate + MAX_UPDATE_GAP)) { for (i = 0 ; i < LED_QTY ; i++) oLED = CRGB::Red; } FastLED.show(); delay(1000); } // Receive data from the I2C bus void receiveI2CData(int iBytes){ // Data received over I2C should conform to the following format: 0xXY where X = LED index and Y = new LED colour byte i, j, sByte, sLED, sColour; if (bDebug == true) { Serial.print("Reading "); Serial.print(iBytes, HEX); Serial.print(" bytes of I2C data."); } i = Wire.available(); if (bDebug == true) { Serial.print(i); Serial.println(" bytes available"); } for (j = 0 ; j < i ; j++) { sByte = Wire.read(); if (bDebug == true) { Serial.print("Read 1 byte: "); Serial.print(sByte,HEX); Serial.println("."); } sLED = (sByte & 0xf0) >> 4; sColour = sByte & 0x0f; if (sLED > 0x07) { // This is not the index of an LED, drop this byte. if (bDebug == true) { Serial.print("LED index is out of range, ignoring this byte ("); Serial.print(sByte, HEX); Serial.println(")."); } return; } if (bDebug == true) { Serial.print("Setting oLED["); Serial.print(sLED); Serial.print("] to "); Serial.print(sColour,HEX); Serial.print(": "); } switch (sColour) { case LED_COLOUR_BLACK: oLED[sLED] = CRGB::Black; if (bDebug == true) Serial.println("Black."); break; case LED_COLOUR_BLUE: oLED[sLED] = CRGB::Blue; if (bDebug == true) Serial.println("Blue."); break; case LED_COLOUR_GREEN: oLED[sLED] = CRGB::Green; if (bDebug == true) Serial.println("Green."); break; case LED_COLOUR_AMBER: oLED[sLED] = CRGB::Gold; if (bDebug == true) Serial.println("Gold."); break; case LED_COLOUR_RED: oLED[sLED] = CRGB::Red; if (bDebug == true) Serial.println("Red."); break; case LED_COLOUR_WHITE: oLED[sLED] = CRGB::White; if (bDebug == true) Serial.println("White."); break; default: if (bDebug == true) Serial.println("Unknown LED colour"); } tLastUpdate = now(); } } // Send data callback - not used, so this is purely for safety void sendI2CData(){ Wire.write(0x00); } Link to comment Share on other sites More sharing options...
Recommended Posts