Reading from Serial

Update.

I am sitting here watching the most beautiful thing ever. a flickering green led!. I got it to work with the following code. I think it all came down to having sending on one com port and receiving on another. once i set NSS up to read and standard serial to transmit, it seems to be working... the led part at least. I am going to go through my code now and change things out so that everything reads on NSS and transmits on hardware serial. I'll let you all know how it goes.

#include <NewSoftSerial.h>
#define LEDpin	13
#define txPin 9

NewSoftSerial mySerial(8,9);
void setup () {

	Serial.begin(115200);
	mySerial.begin(9600);
	
	pinMode(LEDpin, OUTPUT);
	
}

void loop () {
	static byte c;
	
	if (mySerial.available() > 0) {
		c = mySerial.read();
		Serial.println (c, HEX);
		digitalWrite (LEDpin, HIGH);
		delay (100);
		digitalWrite (LEDpin, LOW);
		delay (100);
	}

}

YES!

Serial communication is a go!

Now on to the actual problem. I modified my code with elements from that test sketch so that i can be sure that data is coming through and when i run the carserver client, my light flickers constantly, almost in time with the light on my router. I set this up to println back to the txpin when i have debug turned on and then i used cat < /dev/tts/1 to listen to what was coming across. So basically, the way i see it is that the router is pumping something out, the arduino looks at it and turns around and sends it right back. That data i can see raw in my terminal window... here's the thing. It's just putting out a 0 and a carrige return.... now at some point i had vb6 application that controls the car working to an extent and it put out two 0's and any time i hit a key, it would put out a different number. I cant figure out what has changed. Can you run through my new code and see if i have it set up and reading incorrectly?

 // include the SoftwareSerial library so you can use its functions:
#include <NewSoftSerial.h>
#include <ctype.h>

#define DEBUG 0

#define txPin 9
#define rxPin 8
#define LEDpin 13

NewSoftSerial mySerial(8,9);
int inByte;         // incoming serial byte

#define bit9600Delay 84
#define halfBit9600Delay 42
#define bit4800Delay 188
#define halfBit4800Delay 94

int serialChar; // stores character of serial Input as integer
 
unsigned long decay; // counter from last command
unsigned long decaylimit=100000; // 100,000 is about 5 seconds

 
void setup() {
    // define pin modes for tx, rx, led pins:

  pinMode(LEDpin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  Serial.begin(9600);
  mySerial.begin(115200);
  Serial.println("Hello"); // For debugging purposes
  
 
  //left/right motors
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  //end debugging
}
 
int SWread()
{
  byte val = 0;
  while (digitalRead(rxPin));
  //wait for start bit
  if (digitalRead(rxPin) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rxPin) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay);
    delayMicroseconds(bit9600Delay);
    return val;
  } 
}
void loop() {
  //check for serial communications
 {

  if (mySerial.available()) {
      serialChar = mySerial.read();
      mySerial.println((char)inByte); 
                digitalWrite (LEDpin, HIGH);
		delay (100);
		digitalWrite (LEDpin, LOW);
		delay (100);
    
    // decay counts the age of the last command
    // at the limit (100,000 = ~5 seconds, all signals are shut off
    if (decay > decaylimit) {
      digitalWrite(4, LOW); 
      digitalWrite(5, LOW); 
      digitalWrite(6, LOW); 
      digitalWrite(7, LOW);
      // stop counting at limit, shut off all pins
    }
    else {
      decay++;
    }
   
   {
 
 #if DEBUG     // echo for debugging only:
      Serial.println(serialChar);
 #endif
        // serialChar contains the ASCII code of the *first* character sent over serial when defined as int
        switch (serialChar) {
 
         // logical signals w s a d style     
         case '119': 
           digitalWrite(4, LOW);  
           digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(6, HIGH);            
            decay=0;            
            break;
         case '115': 
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);            
            decay=0;            
            break;
         case '97':  
            digitalWrite(5, HIGH); 
            digitalWrite(6, LOW); 
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;
         case '100': 
            digitalWrite(4, LOW); 
            digitalWrite(6, HIGH); 
            digitalWrite(5, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;            
         case '113': 
            digitalWrite(4, LOW); 
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(7, LOW);
            decay = decaylimit;            

        }
      }
    }
  }
 }
         case '119':

This is almost certainly wrong. Either lose the single quotes, or replace the number in the quotes with the correct letter (preferred).

No go. It doesnt move. I think the code is now set up correctly, but maybe the carserver is sending over characters other than wasd? or is the arduino looking for characters in one form and the carserver is sending them over in another?

 // include the SoftwareSerial library so you can use its functions:
#include <NewSoftSerial.h>
#include <ctype.h>

#define DEBUG 0

#define txPin 9
#define rxPin 8
#define LEDpin 13

NewSoftSerial mySerial(8,9);
int inByte;         // incoming serial byte

#define bit9600Delay 84
#define halfBit9600Delay 42
#define bit4800Delay 188
#define halfBit4800Delay 94

int serialChar; // stores character of serial Input as integer
 
unsigned long decay; // counter from last command
unsigned long decaylimit=100000; // 100,000 is about 5 seconds

 
void setup() {
    // define pin modes for tx, rx, led pins:

  pinMode(LEDpin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  Serial.begin(9600);
  mySerial.begin(115200);
  Serial.println("Hello"); // For debugging purposes
  
 
  //left/right motors
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  //end debugging
}
 
int SWread()
{
  byte val = 0;
  while (digitalRead(rxPin));
  //wait for start bit
  if (digitalRead(rxPin) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rxPin) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay);
    delayMicroseconds(bit9600Delay);
    return val;
  } 
}
void loop() {
  //check for serial communications
 {

  if (mySerial.available()) {
      serialChar = mySerial.read();
      mySerial.println((char)inByte); 
                digitalWrite (LEDpin, HIGH);
		delay (100);
		digitalWrite (LEDpin, LOW);
		delay (100);
    
    // decay counts the age of the last command
    // at the limit (100,000 = ~5 seconds, all signals are shut off
    if (decay > decaylimit) {
      digitalWrite(4, LOW); 
      digitalWrite(5, LOW); 
      digitalWrite(6, LOW); 
      digitalWrite(7, LOW);
      // stop counting at limit, shut off all pins
    }
    else {
      decay++;
    }
   
   {
 
 #if DEBUG     // echo for debugging only:
      Serial.println(serialChar);
 #endif
        // serialChar contains the ASCII code of the *first* character sent over serial when defined as int
        switch (serialChar) {
 
         // logical signals w s a d style     
         case 'w': // 119
           digitalWrite(4, LOW);  
           digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(6, HIGH);            
            decay=0;            
            break;
         case 's': // 115
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);            
            decay=0;            
            break;
         case 'a': // 97  
            digitalWrite(5, HIGH); 
            digitalWrite(6, LOW); 
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;
         case 'd': // 100 
            digitalWrite(4, LOW); 
            digitalWrite(6, HIGH); 
            digitalWrite(5, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;            
         case 'q': // 113
            digitalWrite(4, LOW); 
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(7, LOW);
            decay = decaylimit;            

        }
      }
    }
  }
 }

maybe the carserver is sending over characters other than wasd?

You tell us, you have a debug print there. But change it to

Serial.println(serialChar, HEX);

in case you're getting non-printable values.


Rob

Basically, something like this....

0
0
0
0
0
0
0

and so on. nothing else.

So serialChar is screwed at the point you print it, was it received correctly in the first place. Move you print() around to see where thing start going wrong.


Rob

Are you really using NSS at 115200? If so what are all the bit9600Delay type constants?

I thought you were using 9600 to the router.


Rob

What's a type constant? See how ignorant i am?

I was told by someone (dont know at this point) that the router runs at 115200....

I was told by someone (dont know at this point) that the router runs at 115200

Hardly confidence boosting :slight_smile: You need to know that.

What's a type constant?

All these

#define bit9600Delay 84
#define halfBit9600Delay 42
#define bit4800Delay 188
#define halfBit4800Delay 94

But I now see there aren't being used because SWread() never gets called.

No matter, you have to identify at what point serialChar is bad. As I said a couple of posts ago

Move you print() around to see where thing start going wrong.

I see you are echoing the character back to the router, does that work?


Rob

echoing back to the router does work. It returns 0's as well.

should i remove swread entirely? as well as the type constants? Just to clean things up?

I will try playing with my print debug.

should i remove swread entirely? as well as the type constants? Just to clean things up?

Yep.

It returns 0's as well.

Then that's what you are getting from the router. Add a print just after you get the character to prove it but you have a problem there I'd say.

You must be getting something or .available() would never return a positive number, so I'd look at the buad rate. If you don't have any instruments try all different values until you get the right value.


Rob

Here's the latest revision to my code. I'm trying to wrap my mind around the baud rates. The router sends and receives at 115200. But it too is printing out 0's, so it doesnt sound like my sketch is the problem anymore. it sounds like the carserver is only dumping single digits. I could reflash and try it with whiterussian openwrt, but id rather keep with dd-wrt if i can. I've reflashed and started from scratch so many times that i could probably do it in my sleep, but before i do that, can you take one last look at my code and let me know if im missing anything?

 // include the SoftwareSerial library so you can use its functions:
#include <NewSoftSerial.h>
#include <ctype.h>

#define DEBUG 0

#define txPin 9
#define rxPin 8
#define LEDpin 13

NewSoftSerial mySerial(8,9);
int inByte;         // incoming serial byte

int serialChar; // stores character of serial Input as integer
 
unsigned long decay; // counter from last command
unsigned long decaylimit=100000; // 100,000 is about 5 seconds

 
void setup() {
    // define pin modes for tx, rx, led pins:

  pinMode(LEDpin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  Serial.begin(9600);
  mySerial.begin(115200);
  Serial.println("Hello"); // For debugging purposes
  
 
  //left/right motors
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  //end debugging
}
 
void loop() {
  //check for serial communications
 {

  if (mySerial.available()) {
      serialChar = mySerial.read();
      mySerial.println((char)inByte); 
                digitalWrite (LEDpin, HIGH);
		delay (100);
		digitalWrite (LEDpin, LOW);
		delay (100);
    
       #if DEBUG     // echo for debugging only:
      Serial.println(serialChar, HEX);
    
    // decay counts the age of the last command
    // at the limit (100,000 = ~5 seconds, all signals are shut off
    if (decay > decaylimit) {
      digitalWrite(4, LOW); 
      digitalWrite(5, LOW); 
      digitalWrite(6, LOW); 
      digitalWrite(7, LOW);
      // stop counting at limit, shut off all pins
    }
    else {
      decay++;
    }
   
   {
 
       #if DEBUG     // echo for debugging only:
      Serial.println(serialChar, HEX);

 #endif
        // serialChar contains the ASCII code of the *first* character sent over serial when defined as int
        switch (serialChar) {
 
         // logical signals w s a d style     
         case 'w': // 119
           digitalWrite(4, LOW);  
           digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(6, HIGH);            
            decay=0;            
            break;
         case 's': // 115
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);            
            decay=0;            
            break;
         case 'a': // 97  
            digitalWrite(5, HIGH); 
            digitalWrite(6, LOW); 
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;
         case 'd': // 100 
            digitalWrite(4, LOW); 
            digitalWrite(6, HIGH); 
            digitalWrite(5, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;            
         case 'q': // 113
            digitalWrite(4, LOW); 
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(7, LOW);
            decay = decaylimit;            

        }
      }
    }
  }
}

Ok, so i took a screenie to show you what im talking about. When you press w or up arrow you get 01, s or down, 02, a or left, 04, d or right 08.

The terminal sees it as being put out to serial and streams it, but the serial monitor only shows a single 0 coming into the arduino. Is my code set up to only read the first character? because if so, its only going to read that 0 and not the character after... have a look

 // include the SoftwareSerial library so you can use its functions:
//01 = forward
//02 = backward
//04 = left
//08 = right

#include <NewSoftSerial.h>
#include <ctype.h>

#define DEBUG 1

#define txPin 9
#define rxPin 8
#define LEDpin 13

NewSoftSerial mySerial(8,9);
int inByte;         // incoming serial byte

int serialChar; // stores character of serial Input as integer
 
unsigned long decay; // counter from last command
unsigned long decaylimit=100000; // 100,000 is about 5 seconds

 
void setup() {
    // define pin modes for tx, rx, led pins:

  pinMode(LEDpin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  Serial.begin(115200);
  mySerial.begin(115200);
  Serial.println("Hello"); // For debugging purposes
  
 
  //left/right motors
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  //end debugging
}
 
void loop() {
  //check for serial communications
 {

  if (mySerial.available()) {
      serialChar = mySerial.read();
      mySerial.println((char)inByte); 
                digitalWrite (LEDpin, HIGH);
		delay (100);
		digitalWrite (LEDpin, LOW);
		delay (100);
  
    
{
      Serial.println(serialChar, HEX);
    
    // decay counts the age of the last command
    // at the limit (100,000 = ~5 seconds, all signals are shut off
    if (decay > decaylimit) {
      digitalWrite(4, LOW); 
      digitalWrite(5, LOW); 
      digitalWrite(6, LOW); 
      digitalWrite(7, LOW);
      // stop counting at limit, shut off all pins
    }
    else {
      decay++;
    }
   
   {
 
       #if DEBUG     // echo for debugging only:
      Serial.println(serialChar, HEX);

 #endif
 
 if (mySerial.available()) {
      serialChar = mySerial.read();
      
      
        // serialChar contains the ASCII code of the *first* character sent over serial when defined as int
        switch (serialChar) {
 
         // logical signals w s a d style     
         case 'w': // 119
           digitalWrite(4, LOW);  
           digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(6, HIGH);            
            decay=0;            
            break;
         case 's': // 115
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);            
            decay=0;            
            break;
         case 'a': // 97  
            digitalWrite(5, HIGH); 
            digitalWrite(6, LOW); 
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;
         case 'd': // 100 
            digitalWrite(4, LOW); 
            digitalWrite(6, HIGH); 
            digitalWrite(5, LOW);
            digitalWrite(7, LOW);            
            decay=0;            
            break;            
         case 'q': // 113
            digitalWrite(4, LOW); 
            digitalWrite(5, LOW); 
            digitalWrite(6, LOW); 
            digitalWrite(7, LOW);
            decay = decaylimit;            

        }
      }
    }
  }
 }
}
}

When you press w or up arrow you get 01, s or down, 02, a or left, 04, d or right 08.

You get this where? Is that what the application is sending out? How is it sending the values? As bytes or as strings?

  if (mySerial.available()) {
      serialChar = mySerial.read();

If the data is sent as a binary value, it is read here, and discarded, as nothing more is done with serialChar than to print it.

However, as the serial monitor shows a 0, it appears that the application is sending the value as a string, so the first character is always 0, which is what you see printed.

I have no idea what decal and decayLimit are doing.

Since it appears that the data is sent as a string, and there is a delay after turning the LED on, and another after turning it off, the second character '1', '2', '4', or '8' will have arrived when this code is executed:

 if (mySerial.available()) {
      serialChar = mySerial.read();

Then you have this:

        switch (serialChar) {
 
         // logical signals w s a d style     
         case 'w': // 119
         case 's': // 115
         case 'a': // 97  
         case 'd': // 100 
         case 'q': // 113

Now, the obvious question is why your cases don't match what you say you are sending.

But why is the arduino only seeing the first character? its not going to matter what is being sent to it if all it sees is a 0 with a carriage return. i need two characters before i can change the sketch around.

But why is the arduino only seeing the first character?

How do you know it is only seeing the first character? The fact that you don't echo the result of the second read makes it hard for you to prove that it didn't occur.

Ok, im back and ready to work on this project some more. Sorry for the long interval, i had to move and just now got my internet working again.

Paul, what do i need to be inserting and where, in order to get the second read to make sure there is a second character being sent?

      serialChar = mySerial.read();

Read a character.

      Serial.println(serialChar, HEX);

Echo it.

      serialChar = mySerial.read();

Read another character.

        switch (serialChar) {

Assume that it is good.

Is it really that hard to figure out how to echo what you read?