Need Help Combine Serial with LED

Hi

Don't know if its ok to post my question in this topic but I'm a complete noob and was wondering whether there is a more simple way of doing the same thing as I have done here (sorry if I'm in the wrong place).

/*This code performs the task of switching an led on and off 
 when a char of value '1' is received on the serial port it also 
 prints the current state of the led either "ON" or "OFF" */


#define LED 13    // output pin where the led is connected 

char old_input = '1';  // this stores the begining value 
char input = 0;        // this stores the value of the input 
int state = 0;         // 0 = led off and 1 = led on 

void setup() {
  pinMode(LED, OUTPUT);     // set the led pin as an output 
  Serial.begin(9600);       //initalize the serial port 



}

void loop() {

  if (Serial.available()){                 //check for available serial 

    char input = Serial.read();            //read input value and store it              
    if ((old_input=='1')&&(input=='1')){
      state = 1-state;                     // defines the state 0 or 1
    }
    old_input = input;              //input is old store it 
    if (state == 1){                //if a condition is met write the led high 
      digitalWrite(LED,HIGH);
      Serial.println("ON");         //print the state back to the port 

    }
    else if (state == 0){           //if the condition is anything else write the led low
      digitalWrite(LED,LOW);
      Serial.println("OFF");        //print the state back to the port 
    }

  }
}

Thanks Jon Czudek

Moderator Edit: Split to a separate topic.

if (state == 1){                //if a condition is met write the led high 
      digitalWrite(LED,HIGH);
      Serial.println("ON");         //print the state back to the port 

    }
    else if (state == 0){           //if the condition is anything else write the led low
      digitalWrite(LED,LOW);
      Serial.println("OFF");        //print the state back to the port 
    }

If state can only be 1 or 0, then there is no need to test if it is 0, having already tested to see if it is 1 digitalWrite(LED, state); would be simpler. Or, if you're worried about the values of HIGH and LOW changing: digitalWrite(LED, state ? HIGH : LOW);

Hi

Thanks I'll try that

Jon Czudek

Looks to me as though you can dispense with old_input too. I assume that you want typing a '1' to flip the state of the LED, and your code does that, if you keep on typing '1's. Try typing a '0' though and the next '1' will not do anything. Of course, you may have a good reason for this if you're still adding functionality.

Hi

I’ve changed my code to switch case and two input values ‘l’ on and ‘L’ off but I also have an extra input of ‘t’ which then prints back the temp from a dallas sensor to my iphone the problem I’m having is that the code runs fine and everything works but then the temp response just prints Temp C after some time I then send the command again and get the remainder 24.09 eg, reading but then I push the led on button and the response is Temp C 24.09 instead of ON and from then on all the responses are all mixed up. The only thing is that the led turn on when on is pushed and off if off is pushed just the responses are all over the place. I’ve run this code using just the serial monitor and it seems to work fine but when I run it over the wifi (dfrobot serial to wifi) to the iphone (mote application) it has this issue just wondering if my code is ok. Let me know if you need to know anything else.

/*This code performs the task of switching an led on and off 
 when a char of value 'l' or 'L' is received on the serial port it also 
 prints the current state of the led either "ON" or "OFF" and it also 
 prints back the temperature when command 't is receieved*/


#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

#define LED 13    // output pin where the led is connected 



void setup() {
  pinMode(LED, OUTPUT);     // set the led pin as an output 
  Serial.begin(9600);  //initalize the serial port 
  sensors.begin();

}

void loop() {

  if (Serial.available()){                 //check for available serial 

    char input = Serial.read();            //read the char from the buffer
    switch (input){                        //using switch case to transfer inputs into actions
    case 'l':
      digitalWrite(LED,HIGH);
      Serial.println("ON");
      delay(500);
      break;

    case 'L':
      digitalWrite(LED,LOW);
      Serial.println("OFF");
      delay(500);
      break;

    case 't':
      sensors.requestTemperatures();               //get temperature from sensor 
      delay(300);
      Serial.print("Temp C  ");
      Serial.println(sensors.getTempCByIndex(0));  //Print the temeperature value 
      delay(500);
      break;
    }
  }
}

Thanks
Jon Czudek

but then the temp response just prints Temp C after some time I then send the command again and get the remainder 24.09 eg, reading but then I push the led on button and the response is Temp C 24.09 instead of ON and from then on all the responses are all mixed up.

There is nothing wrong with the Arduino code. It is sending what it is supposed to send, when it is supposed to send it.

The problem is clearly on the other end - not properly reading the serial data that is sent.

The only thing I would question with this code is that in loop, you only do something if there is serial data available. After reading each character that is understood, you delay before reading the next character. Why? If the sending application sends "lLlLlLlLlL", I'd expect the LED to go on and off as fast as possible.

Hi

Thanks for the reply and yes you are right it is at the receiving end because I tried a terminal app on the Iphone and it worked fine, the mote app must only be able to receive single line responses and with the delay I do believe you are right I really don't know why I put them there. :~

Thanks Jon Czudek

Try using snprintf to get the entire temp output into a buffer and then send that. Perhaps it'll have a better effect on the mote.

Try using snprintf to get the entire temp output into a buffer and then send that. Perhaps it'll have a better effect on the mote.

How? There is very little delay between writing the "Temp C " part and the value part.

The mote should be reading to the delimiter that is sent after the value (the carriage return/line feed). If it isn't, using one Serial.print() statement instead of two will not change anything.

Frankly, It's the only thing I can think of to change in the arduino code that might improve things. I'm curious about how long this sensors.getTempCByIndex(0) takes and whether the mote times out & sends what it has. But you're likely right - it'll make no difference. Try it anyway, at least it'll provide a bit more info.

I'm curious about how long this sensors.getTempCByIndex(0) takes

Well, that's certainly a good point. Calling the function, and storing the results in a variable, and then sending the serial data would eliminate that as a cause for concern, without the overhead (code bloat) of a call to sprintf or a variation.

Hi

Thanks for the replies. With the mote app I can change the timeout which I have already done, still the issue persists. With the snprintf if anyone could show me how to implement it I would be very grateful as I'm a complete noob and really only know the basics.

Your help is much appreciated Jon Czudek

Try it the way PaulS suggested:

    case 't':
      int temperature;
      sensors.requestTemperatures();               //get temperature from sensor 
      delay(300);
      temperature=sensors.getTempCByIndex(0);
      Serial.print("Temp C  ");
      Serial.println(temperature);  //Print the temperature value 
      delay(500);
      break;

But don't get your hopes up ;)

Hi

I've tried the code and nope it doesn't work. How would you get the "Temp C " and sensors.getTempCByIndex(0); into one Serial.println, that is if it is possible to do that, printing a string and float together.

Thanks for the help Jon Czudek

The time it takes between the first print statement to complete and the second print statement to construct the string to send and to begin sending it is very, very, very short. I seriously doubt that that few nanosecond delay is what is causing the other application to split the strings.

Hi

The funny thing is that it only starts to split the strings after about 5-10 times of requesting the temperature, so in every day use you wouldn't request the temp that many times without quitting the app at some point (the issue resolves for another 5-10 requests if the app is quite and then reopened). Or I could just print the float without the "Temp C ", but still it is a bug and some how it needs to get resolved maybe I might get a brain wave.

Maybe I should just learn how to program my own Iphone app that would fix it

Thanks for your help all Jon Czudek