1

I am writing a program that is currently set up like so:

Python script running on my computer. Raspberry pi is the broker for the mqtt data transmission An ESP8266 is programmed to listen to/subscribe to data coming through on a specific channel.

The data comes through with this format: "255,255,255" for example. It is parsed on the "," saving the values to apply to the red green and blue channel of an led.

I can manually type colors to send from my python program and the led updates correctly. When I update the python script to send a stream of values that produce an effect of fading through the rainbow, that also works for the most part BUT, the data gets sent so quickly and it seems to get backed up. This causes the LED to continue running through the loop even after I stop the python program. The longer the program runs before I stop, the longer the led continues fading after stopping.

This is a problem because I was hoping to scale this up greatly to control many led strips throughout my house. I imagine I could slow down the rate at which I send values, I would need to find the sweet spot of how fast I could send values without them getting backup (because if I change the pattern I want the change to happen immediately, and to not need to wait for all the values of the previous pattern to complete) This gets harder with the more individual strips I try to control at once.

Is there a more efficient way to parse the incoming values? callback() and splitAndSaveRGBValues() handle parsing the values

The esp8266 code is:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>


#define CLIENT_NAME "ESP8266_1" // just a name to identify this client
WiFiClient wifiClient;
PubSubClient mqttClient("10.0.0.131", 1883, wifiClient);

//set rgb led pins
int pinGreen = 4;
int pinBlue = 14;
int pinRed = 12;

void setup() 
{
  Serial.begin(9600);
  //set rgb led pins to output

  pinMode(pinRed, OUTPUT);
  pinMode(pinGreen, OUTPUT);
  pinMode(pinBlue, OUTPUT);
  digitalWrite(pinRed, HIGH);
  digitalWrite(pinGreen, HIGH);
  digitalWrite(pinBlue, HIGH);

  mqttClient.setCallback(callback);
  WiFi.begin("partyHouse", "whatsthepassword");
  connectToWiFiAndBroker();
}

void connectToWiFiAndBroker() 
{
  Serial.print("\nConnecting to WIFI");
  while (WiFi.status() != WL_CONNECTED) 
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to WIFI!");

  Serial.println("Connecting to broker");
  while (!mqttClient.connect(CLIENT_NAME)) 
  {
    Serial.print(".");
    delay(500);
  }
  Serial.println("Connected to broker!");

  mqttClient.subscribe("InterestingTopics/#");
}

//savaing for use when sending data 

//#define MILLISEC_DELAY_BETWEEN_PUBLISH 10000
//unsigned long lastTime = 0;
//unsigned long currentValue = 1;
//char msg[50];

void loop() 
{
  if (!mqttClient.connected()) 
  {
    connectToWiFiAndBroker();
  }

  mqttClient.loop();
  //Savaing as a refernce for how to send data

  //  if(millis() - lastTime > MILLISEC_DELAY_BETWEEN_PUBLISH) 
  //  {
  //    lastTime = millis();
  //    Serial.println("Publishing a new value");
  //    snprintf (msg, 75, "%ld", currentValue);
  //    Serial.println(currentValue);
  //    mqttClient.publish("ESP8266/CurrentValue", msg);
  //    currentValue++;
  //  }
}
int red;
int green;
int blue;

//the topic is the path based on the subscription
void callback(char* topic, byte* payload, unsigned int length) 
{
  char colorCommand[length+1];
  for (int i = 0; i < length; i++) 
  {
    colorCommand[i] = (char)payload[i];
  }
  colorCommand[length+1] = '\0';
  splitAndSaveRGBValues(colorCommand);
  updateRGBFromIncomingValues();
}
void splitAndSaveRGBValues(char *colorCommand) {
  char *color;
  color = strtok (colorCommand,",");
  red = atoi(color);
  int increment = 1;
  while (color != NULL)
  {
    color = strtok (NULL, ",");
    if (increment == 1) {
      green = atoi(color);
    } if (increment == 2) {
      blue = atoi(color);
    }
    increment ++;
  }
}

void updateRGBFromIncomingValues() {
  analogWrite(pinRed, red);
  analogWrite(pinGreen, green);
  analogWrite(pinBlue, blue);
}

I have considered changing the approach from streaming values constantly, to coding patterns that could be called from functions saved on each device, but I would need to upload need code (containing the additional patterns for use) to each device each time I think of a new pattern. Current approach would allow patterns to be created on my computer and the path used with the MQTT would control which chip to send values to. The con of my current approach is that leds would only work if I was running the program on my computer to control them (Id like the leds to be able to run their previous pattern if freshly turned on).

I am completely open to suggestions on different ways I can attempt to accomplish my goals if my current approach is insufficient: many nodes/arduinos that have X number of led strips that could be controlled individually, or sync'd up. That would run the previous pattern if turned on, and could be controlled from a single interface

  • you need to identify the data bottleneck ... if you have to throttle the python script on your computer, then the bottleneck may be between the computer and the MQTT server ... until then, the post is not about the arduino – jsotola Nov 19 '19 at 6:02
  • I thought the bottle neck was the parsing of the data, due to the symptoms from sending data quickly. Is that not right? – Jordan Klaers Nov 19 '19 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.