0

I've been struggling with writing a code for Arduino UNO so that I could use my phone and change the colour of the LED strip via terminal.

#include <FastLED.h>
#include <SoftwareSerial.h>

SoftwareSerial btSerial(2, 4); // RX, TX

#define NUM_LEDS 22
#define DATA_PIN 6
CRGB leds[NUM_LEDS];

void setup() { 

  btSerial.begin(9600);
  btSerial.println("Connected to Arduino");
  FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);
}

char a;

void loop()
{
    if (btSerial.available())
    {
      a= (char)btSerial.read();

      if(a=="b")
      {
        btSerial.println("Turning LED blue");
        leds[0] = CRGB::Blue; // Turns 1 LED to blue
        FastLED.show();
      }
    }
}

So basically I'd like to be able to change LED colours with my phone. If you enter "r", the LEDS turn red, if you enter "b", leds turn blue etc. Maybe even add some patterns. Brightness controller would be nice too to save some battery.

EDITED. Serial works.

#include <FastLED.h>
#include <SoftwareSerial.h>

SoftwareSerial btSerial(2, 4); // RX, TX

#define NUM_LEDS 22
#define DATA_PIN 6
CRGB leds[NUM_LEDS];

void setup() { 
  Serial.begin(9600);
  btSerial.begin(9600);
  btSerial.println("Connected to Arduino");
  FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);}

char a;

void loop(){
    if (btSerial.available())
    Serial.write(btSerial.read());
    if (Serial.available())
    btSerial.write(Serial.read());}

3.

#include <FastLED.h>
#include <SoftwareSerial.h>

SoftwareSerial btSerial(2, 4); // RX, TX

#define NUM_LEDS 22
#define DATA_PIN 6
CRGB leds[NUM_LEDS];

void setup() { 
  Serial.begin(9600);
  btSerial.begin(9600);
  btSerial.println("Connected to Arduino");
  FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);}

char a;

void loop(){
    if (btSerial.available())
    Serial.write(btSerial.read());
    if (Serial.available())
    btSerial.write(Serial.read());}

    if (a=='b'){
      btSerial.println("Turning LED blue");
      leds[0] = CRGB::Blue;
      FastLED.show();}

RECENT:

#include <FastLED.h>
#include <SoftwareSerial.h>

SoftwareSerial btSerial(2, 4); // RX, TX

#define NUM_LEDS 28
#define DATA_PIN 6
CRGB leds[NUM_LEDS];

void setup()
{ 
  Serial.begin(9600);
  btSerial.begin(9600);
  btSerial.println("Connected to Arduino");
  FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);
}

char a;

void loop()
{
  if (btSerial.available())
  {
    a= (char)btSerial.read();

    if( a == 'b' )
    {
      btSerial.println("Sinine"); //All LEDs are blue
      fill_solid( leds, NUM_LEDS, CRGB::Blue);
      FastLED.show();
    }

    if( a == 'r' )
    {
      btSerial.println("Punane"); //All LEDs are red
      fill_solid( leds, NUM_LEDS, CRGB::Green);
      FastLED.show();
    }

    if( a == 'g' )
    {
      btSerial.println("Roheline"); //All LEDs are green
      fill_solid( leds, NUM_LEDS, CRGB::Red);
      FastLED.show();
    }

    if( a == 'y' )
    {
      btSerial.println("Sinine"); //All LEDs are yellow
      fill_solid( leds, NUM_LEDS, CRGB::Yellow);
      FastLED.show();
    }

    if( a == 'w' )
    {
      btSerial.println("Sinine"); //All LEDs are white
      fill_solid( leds, NUM_LEDS, CRGB::White);
      FastLED.show();
    }

    if( a == 'o' )
    {
      btSerial.println("Väljas"); //All LEDs are turned off
      fill_solid( leds, NUM_LEDS, CRGB::Black);
      FastLED.show();}

    if ( a == 'z' ) //1 blue LED from start to finish
    {
      int i= 2; 
      while (i > 0)
      { 
        for (int dot = 0; dot < NUM_LEDS; dot++)
        { 
            leds[dot] = CRGB::Blue;
            FastLED.show();
            leds[dot] = CRGB::Black;
            delay(100);
        }
      }
    }

     if ( a == 'x' ) //1 red LED from start to finish
     {
      int i= 2;
      while (i > 0)
      {
        for (int dot = 0; dot < NUM_LEDS; dot++) 
        { 
            leds[dot] = CRGB::Green;
            FastLED.show();
            leds[dot] = CRGB::Black;
            delay(100);
        }
      }
     } 
  }
}
  • 1
    And what exactly is your question? Your code doesn't include much Serial stuff. Do you want to know, how to read from Serial? Then have you looked at the bunch of tutorials inside the Arduino IDE or on the web? Or do you have problems with the LEDs? Then, have you tried to use and understand the examples, that come with the FastLED library? Currently it is unclear, what exactly your problem is – chrisl Jan 11 at 23:33
  • You still didn't ask a real question, so we don't know, what the problem with your code is. Btw: You might want to try and replace the double quotes in your if statement by single quotes, since here you want to compare single characters (which are represented by single quotes around a single character) and not string literals (which are represented by double quotes around multiple characters). – chrisl Jan 12 at 0:15
  • I need to get the serial read working, right now it gives me nothing when I type on my phone. – Janar Jan 12 at 0:37
  • I deleted some stuff and got serial working. Not sure like how I read what I type from the phone and then how I make them into if commands. – Janar Jan 12 at 0:44
  • I can see the messages both ways. Not sure how to put that into code. "If this(specific text, for example "r" gets typed into serial via phone then leds change color to red)". – Janar Jan 12 at 0:49
1

You seem to lack the basic understanding, how Serial (UART) communication works. So I will explain the basic principles. From there you should be able to implement, what you want.

Serial (aka UART) transmits the data serially, byte after byte (thus it's name). When you type in a text in the Serial Monitor of the Arduino IDE and send it, you have no influence, when exactly each byte will be transmitted. As the UART interface doesn't know messages or "chunks of data", only bytes, it will transmit each byte, when it is ready. There might be a short pause inbetween the bytes. This is an important fact to know, if you want to implement commands longer than 1 byte.

The normal Serial interface is mostly implemented in the Uno's hardware, thus it doesn't depend on the running software that much. SoftwareSerial does all the hard communication work in software, thus it comes with some caveats (blocking write operations, more limited baudrate, only possible to receive on one SoftwareSerial interface at once, ...). But both mostly share the same code interface.

Serial.available() returns the number of received bytes, that are still in the internal buffer. You are already using this to only read from the buffer, when there is actually data to read in it (with the if statement). Then you read one byte from the buffer by Serial.read(). Currently you are giving the return value (the read data) directly to the other serial interface for sending. Thus the value is not saved anywhere in your sketch. Doing a Serial.read() will remove the read byte from the buffer and return it. Thus the read byte will no longer be in the buffer.

The code with the 2 if statements and serial functions is mostly used to forward the data between the two serial interfaces. For your use case you don't need this. Instead you should read the data into a local variable like you did in your first sketch:

if (btSerial.available())
{
  a= (char)btSerial.read();

  if(a=="b")
  {
    btSerial.println("Turning LED blue");
    leds[0] = CRGB::Blue; // Turns 1 LED to blue
    FastLED.show();
  }
}

Here you are first checking, if there is data to read in the btSerial buffer. If yes, you read it into the variable a. This variable now holds a single character. If you also want to forward this character to Serial, you can now use Serial.write(a); to do so. Then you want to check the value of the received character. Here we are doing a little excourse:


In C/C++ 2 different kinds of quotes are used: The double quotes " and the single quotes '. Double quotes mark string literals, which consists of a series of characters. Single quotes mark single character values - only one character. In your if statement you check for equality. If you think about it, you see, that checking if 2 single characters are equals is a lot easier, than checking if two strings are equal (checking 1 character on each side versus checking multiple characters on each side). Thus it is a difference, if you compare string literals or single characters. Comparing a single character variable with a string literal doesn't work - they are two completely different things. Instead you should compare the character variable to a single character:

if( a == 'b' )

As you are adding more commands for your project, you will see, that if statements don't order the code very good. In this case a switch statement is better:

switch(a){
    case 'b':
        // Doing what you want to do with the LEDs here
        break;
    case 'c':
        ...
        break;
}

This will execute the corresponding code part depending on the value of a. You can read more about this construct on the web (google something like "C switch").


Now you should be able to implement simple 1 byte/character commands in your code. Also review and understand the examples from the Arduino IDE about Serial.

If you need more complex commands (maybe with some payload data in addition to the command), you have to introduce a communication protocol onto the Serial interface. The simplest way is to define whole messages by using a delimiter character at the end of every message. Mostly the newline '\n' character is used for this purpose. You basically read the data from Serial and save it on a char-array/string until you received the newline character. Then you know, that you have received a complete message, and you can start to process it as a whole. When finished, you clear your message buffer and again wait for a new message. For this to work, you of course have to ensure, that the delimiter character is never part of your send data (as the code would think, that it marks the end of the message).

You can see this in the SerialEvent example in the Arduino IDE. Try to understand, what happens there. There are also many tutorials on the web.

I hope, I could enlighten you a bit. Good luck with your project.

|improve this answer|||||
  • Thank you so much Chris! Got it to work. Now currently working on different patterns and making a phone app. Got basic colours working. – Janar Jan 12 at 18:13
  • If you think, that my answer was correct, you can mark it as tze correct answer. That way others know, that this question is solved. Thanks – chrisl Jan 12 at 18:57
  • Edited the code. So I can control the normal colours via phone app now which I made myself. Now I'm having difficulties creating more interesting patterns. I managed to make a while loop inside void loop() but the loop is not going to end. Got suggested to add another loop into while loop but not sure how that should look. Decided not to use switch statement since currently everything is working fine (unless it's needed to make the other patterns to work). Cheers, really appreciate the help so far. – Janar Jan 12 at 21:05
  • Deleted the rows "int i= 2;" and "while (i > 0)", replaced it with "while (!btSerial.available())", it's working perfectly now. :) – Janar Jan 12 at 22:15
  • So when I send anything to serial it stops the while loop. – Janar Jan 12 at 22:15

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.