Arduino Forum

Topics => Robotics => Topic started by: jair2k4 on Nov 27, 2011, 08:08 pm

Title: Reading from Serial
Post by: jair2k4 on Nov 27, 2011, 08:08 pm
Ok guys, here's the setup

Computer -> wifi - > wrt54gs linksys router -> sparkfun logic level converter to 5v -> Arduino software serial on pins 8 and 9 on a Seeeduino board -> DFrobot dual H bridge driver shield -> tyco rebound RC chassis (same drive style as a tank chassis).

I can send data over serial from the arduino and using cat < /dev/tts/1 my router can see it in SSH. I cannot get data to send the other way to the arduino. In order to get commands to the h bridge and from there to the motors, i need to send data through the router over serial to the arduino.

This is based off of Jon Bennett's project (http://www.jbprojects.net/projects/wifirobot/)

Here is my code. I have tried 2 different routers with the exact same result. I am sure at this point it is a matter of coding to get my arduino to see the serial data. Jon had mentioned something about calling SWread to me, but i dont know enough about linux or processing to do this right. Can you guys give me a hand here? Again, If i set up a sketch to println something like "hello", i can see it just fine over ssh or telnet on the router. It's the communication going the other way that is necessary, and of course the one thing that isnt working for me.

Code:

Code: [Select]
// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>
#include <ctype.h>

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

int serialChar; // stores character of serial Input as integer
int serialLoop; // counter for serial read loop



unsigned long decay; // counter from last command
unsigned long decaylimit=100000; // 100,000 is about 5 seconds

#define rxPin 8
#define txPin 9
#define ledPin 13

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
byte pinState = 0;

void setup() {
   // define pin modes for tx, rx, led pins:
 pinMode(rxPin, INPUT);
 pinMode(txPin, OUTPUT);
 pinMode(ledPin, OUTPUT);
 // set the data rate for the SoftwareSerial port
 mySerial.begin(9600);
 mySerial.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 (SWread() > -1) {

   // 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++;
   }

   // this loop read whole strings. as soon as a string is detected
   // each character is evaluated. We only care about the first one.
   for (serialLoop=0; serialLoop < 16 && Serial.available(); serialLoop++) {
     serialChar = Serial.read();

     // echo for debugging only:
     mySerial.print(serialChar);

     // only do evaluation on the first letter (first loop)
     if (serialLoop==0) {

       // 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 any change shuts off previous command        
        case 119: //w - forward, pin 6+8
           digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
           digitalWrite(4, HIGH);
           digitalWrite(6, HIGH);            
           decay=0;            
           break;
        case 115: //s - backwards, pin 7+9
           digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(7, HIGH);            
           decay=0;            
           break;
        case 97: //a - left, pin 6+9
           digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
           digitalWrite(4, HIGH);
           digitalWrite(7, HIGH);            
           decay=0;            
           break;
        case 100: //d - right, pin 7+9
           digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
           digitalWrite(5, HIGH);
           digitalWrite(6, HIGH);            
           decay=0;            
           break;            
        case 113: //q - stop, pin 6+7+8+9 off
           digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
           decay = decaylimit;            
           break;            
       }
     }
   }
 }
}
Title: Re: Reading from Serial
Post by: PaulS on Nov 27, 2011, 11:46 pm
A couple of comments.
Code: [Select]
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);
SoftwareSerial is obsolete. NewSoftSerial is a much better replacement.

Code: [Select]
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

You told the SoftwareSerial instance that these were its pins. What are you messing with them?

Title: Re: Reading from Serial
Post by: jair2k4 on Nov 28, 2011, 12:13 am
The code i am using is a kludge together of a bunch of different codes that i have been playing with. I have upgraded to new software serial. Please take a look and tell me what the issue could be. I can still send data from the arduino to the router, but the arduino does not see anything coming from the router.

I wired the rx and tx pins from the router together, ran two ssh windows and did this

window# 1

cat /dev/tts/1

window # 2

echo "test" /dev/tts/1

Test shows up in window 1, which tells me that the router is sending and receiving serial data correctly. It HAS to be something in my code. Here is what i am using now:

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

#define rxPin 8
#define txPin 9
#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
int serialLoop; // counter for serial read loop



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
  mySerial.begin(115200);
  mySerial.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()) {
      Serial.println((char)inByte);
//      Serial.print((char)mySerial.read());
     inByte = mySerial.read();
     if ((char)inByte == '1'){
       digitalWrite(13, HIGH);   // set the LED on
       mySerial.println("Light is On");
     }
     if ((char)inByte == '0'){
       digitalWrite(13, LOW);   // set the LED off
       mySerial.println("Light is Off");
     }

    // 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++;
    }

    // this loop read whole strings. as soon as a string is detected
    // each character is evaluated. We only care about the first one.
    for (serialLoop=0; serialLoop < 16 && Serial.available(); serialLoop++) {
      serialChar = Serial.read();

      // echo for debugging only:
      mySerial.print(serialChar);

      // only do evaluation on the first letter (first loop)
      if (serialLoop==0) {

        // 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 any change shuts off previous command       
         case 119: //w - forward, pin 6+8
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(4, HIGH);
            digitalWrite(6, HIGH);           
            decay=0;           
            break;
         case 115: //s - backwards, pin 7+9
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(5, HIGH);
            digitalWrite(7, HIGH);           
            decay=0;           
            break;
         case 97: //a - left, pin 6+9
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);           
            decay=0;           
            break;
         case 100: //d - right, pin 7+9
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(5, HIGH);
            digitalWrite(6, HIGH);           
            decay=0;           
            break;           
         case 113: //q - stop, pin 6+7+8+9 off
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            decay = decaylimit;           

        }
      }
    }
  }
}
}



Title: Re: Reading from Serial
Post by: PaulS on Nov 28, 2011, 12:42 am
Quote
It HAS to be something in my code.

Possibly. But, for code that determines whether the Arduino can send data, or receive data, that code is WAY to complex.

Try something much simpler that blinks an LED when data is received, and sends that data back out.

Until what comes in makes sense, developing complex code to use that data doesn't make sense.

Unplug the motors, and put them back in the box. Remove all code for manipulating the motors.

Get rid of unused functions.

Code: [Select]
      Serial.println((char)inByte);
     inByte = mySerial.read();

Is the Arduino supposed to be clairvoyant? Print a character, then read it.

Code: [Select]
    for (serialLoop=0; serialLoop < 16 && Serial.available(); serialLoop++) {
What is the significance of looping 16 times?

Code: [Select]
         case 119: //w - forward, pin 6+8
Why not:
Code: [Select]
case 'w': // No comment needed
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 28, 2011, 12:55 am
My apologies,

Again, this code was all thrown in together from stuff i have found on the net. I am a novice when it comes to both linux and processing. I really dont know what to do or how to modify the code from this point forward... to be quite honest, i am amazed that i got this far.

I dont know how to manipulate the other code, but as for the cases, i believe they mean that if the arduino receives that number, then it needs to turn on or off the pins specified (as they are the pins that go out to the motor controller). Changing it to 'w' would mean that when 'w' is sent, the pins must be written high or low. The signal being sent from the car server app on the router is sending these specific numbers. If i change that, it will break everything.

I removed the comments, as they were a carry over from the code i copied from. Could you possibly help modify the code with the necessary changes? Any way to print in whatever is received from the router into the serial console in the arduino software? Thats what ive been working on for 2 days, which is why i'm getting so frustrated. I cant even do something as simple as that. Remember, I think the case functions have to stay the way they are.

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

#define rxPin 8
#define txPin 9
#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
int serialLoop; // counter for serial read loop



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
  mySerial.begin(115200);
  mySerial.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()) {
      Serial.println((char)inByte);
//      Serial.print((char)mySerial.read());
     inByte = mySerial.read();
     if ((char)inByte == '1'){
       digitalWrite(13, HIGH);   // set the LED on
       mySerial.println("Light is On");
     }
     if ((char)inByte == '0'){
       digitalWrite(13, LOW);   // set the LED off
       mySerial.println("Light is Off");
     }

    // 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++;
    }

    // this loop read whole strings. as soon as a string is detected
    // each character is evaluated. We only care about the first one.
    for (serialLoop=0; serialLoop < 16 && Serial.available(); serialLoop++) {
      serialChar = Serial.read();

      // echo for debugging only:
      mySerial.print(serialChar);

      // only do evaluation on the first letter (first loop)
      if (serialLoop==0) {

        // 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 any change shuts off previous command       
         case 119:
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(4, HIGH);
            digitalWrite(6, HIGH);           
            decay=0;           
            break;
         case 115:
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(5, HIGH);
            digitalWrite(7, HIGH);           
            decay=0;           
            break;
         case 97:
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);           
            decay=0;           
            break;
         case 100:
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            digitalWrite(5, HIGH);
            digitalWrite(6, HIGH);           
            decay=0;           
            break;           
         case 113: //q - stop, pin 6+7+8+9 off
            digitalWrite(4, LOW); digitalWrite(5, LOW); digitalWrite(6, LOW); digitalWrite(7, LOW);
            decay = decaylimit;           

        }
      }
    }
  }
}
}



Title: Re: Reading from Serial
Post by: graynomad on Nov 28, 2011, 02:23 am
Quote
I think the case functions have to stay the way they are.

Why is that?

119 = 'w'
115 = 's'
97 = 'a'
100 = 'd'
113 = 'q'

so as PaulS said

Code: [Select]
case 119:

is the same as

Code: [Select]
case 'w':

Why make life difficult? He wasn't suggesting that you just remove the comments, but that if the code was written correctly you wouldn't need them in the first place.

But that's by the by until you can prove the basic hardware works, once again, as PaulS said

Quote
Try something much simpler that blinks an LED when data is received, and sends that data back out.


Put that code aside for the moment and use small easily tested steps to build up to the final result.

______
Rob
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 28, 2011, 04:11 am
Cant stress this enough.... very limited knowledge of processing. You might say im a complete idiot.

Now here is the part where you all start flaming me... does anyone have anything already written that can do this? I can build a freaking robot but i cant write a simple code. Shows you my level of expertise.

I'm researching and trying to learn this as i type this very message, but until i find an answer.... help please?

EDIT:

Just tried this and it didnt work.....

Code: [Select]
#include <LED.h>
#include <NewSoftSerial.h>
#define rxPin 8
#define txPin 9

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

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

LED led = LED(13);   // the pin that the LED is attached to

void setup() {
   mySerial.begin(115200);
  mySerial.println("Hello"); // For debugging purposes
  led.blink(250, 2);}  // initialize serial communication:

void loop()
{
  int numMails = 0;

  delay(2000);

  switch (Serial.available()) {
    /* Serial.available() is the number of bytes waiting.  Convert from
     * ASCII val to an int.  Intentional switch-case fall through below.
     */
    case 3:
numMails = Serial.read();
numMails -= 48;
numMails *= 10;
    case 2:
numMails += Serial.read();
numMails -= 48;
numMails *= 10;
    case 1:
numMails += Serial.read();
numMails -= 48;
break;
    default:
/* If >3 chars, just clear out the incoming buffer. */
while (Serial.available())
  Serial.read();
return;

  }
led.blink(400, numMails);
}

Title: Re: Reading from Serial
Post by: PaulS on Nov 28, 2011, 01:58 pm
Code: [Select]
  switch (Serial.available()) {
Serial data transmission is ssslllooowww. You might send 3 bytes at once, but only one might have arrived by the time this code is executed.

So, you treat the number of emails as though the sender sent a 1 digit number.

Quote
Just tried this and it didnt work.....

Yes, it did. It might not have produced the results you wanted, but the code did something. You need to describe what it did, and what you expected it to do.

I'd strongly suggest that you dump whatever it is that is sending data to the Arduino until you are CERTAIN that the Arduino is reading serial data correctly, and producing the correct output based on the serial data that it receives.

Send the Arduino data using the Serial Monitor, and have the Arduino send data back to the Serial Monitor.

When the Arduino reacts properly to the serial data, while sending data back, comment out the calls to send data back, to make sure that the time taken to send the data is not affecting the processing of the data being sent to the Arduino.

When the Arduino produces accurate results without echoing any data, then you can return to your current data source, and work out whether the Arduino is getting data, separate from whether it is processing that data correctly.

Quote
very limited knowledge of processing.

What does knowledge of Processing have to do with anything? Surely you haven't figured out how to run Processing on the router have you?

Instead of trying to debug Processing, wifi, the router, the level shifter and a bunch of other stuff at once, break the problem down into testable pieces.
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 28, 2011, 06:08 pm
I expected it to blink an led on the arduino (pin 13) when serial data was sent. It did not.

As for knowledge of processing.... The best I can do is take someone else's code and strip it down to suit my needs. I cant write my own stuff from scratch. I havent been able to do that with a programming language since HTML 5.0 came out. heh. I know how people hate it when someone comes in here and goes "waaaaa. write my code for me!" which is why I am not asking you to do so. I am trying to learn how to do this myself by reverse engineering others's codes, but it is backfiring in my face. With this type of coding, if i miss one small thing, i screw everything up.

I dont even know how to get it to loop a code around. when i type something in the serial monitor, it doesnt come back in. I think I had it working using the really basic serial code from the wiki. One thing i can say for certain. I am trashing newsoftserial. I havent been able to get it to work at all. no matter what i do. I was using it and SoftwareSerial because someone told me there might be an issue with communication because my router and arduino might both be using the UART, but i do not think this is the case. Can anyone confirm this part? If i can just go back to using hardware serial knowing for certain that it should work, that would be a great deal of stress off of my shoulders there.

Paul, you tell me to dump anything that is coming out to the arduino until i am sure that it is working properly. That is all i am trying to do actually. If i could get my router to dump a simple "hello world" to my serial monitor at this point, i think i would jump 12 feet in the air. What code would i call to make this happen?

Graynomad and Paul, you have both been very understanding so far and so i hope you dont take this wrong, but any help with a viable test sketch you can give me would help IMMENSELY. I would be able to dissect it and learn it, which would probably tell me all i need to know about how to get these two to talk together. Remember, i am not asking you to write my project for me. I am just deferring to the experts here. I know when I am beaten, and i think i bit off more than i could chew on this particular project. But with the countless hours i have dumped into it, it is too late to abandon it at this point.

Thank you again, and i hope you done flame me for being a noob.
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 29, 2011, 04:11 am
Sorry for the double post, but i have been waiting all day hoping someone will lend a hand. Does anyone have some code or can make some code that will flash a led any time serial data is received and then print it into the arduino serial monitor?
Title: Re: Reading from Serial
Post by: graynomad on Nov 29, 2011, 04:19 am
This might get you started,

Code: [Select]

#define LEDpin 13

void setup () {

Serial.begin(115200);
Serial1.begin(4800);

pinMode(LEDpin, OUTPUT);

}

void loop () {
static byte c;

if (Serial1.available() > 0) {
c = Serial1.read();
Serial.println (c, HEX);
digitalWrite (LEDpin, HIGH);
delay (100);
digitalWrite (LEDpin, LOW);
delay (100);
}

}



It will miss a lot of characters because of the delay()s but you should see something.

______
Rob
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 29, 2011, 05:32 am
Thanks Graynomad. Isn't Serial1 only for the mega though? will this still work if i remove the 1 from everything?

Edit: I tried it without the second serial port and removed the '1' after Serial and it flashes whenever i input text from the console, but not when i have the bot hooked up... Hrmm. baud rates are all ok. What am I doing wrong? Should i set up swserial and read on that port and send on a different one?

Code: [Select]
#define LEDpin 13

void setup () {

Serial.begin(115200);


pinMode(LEDpin, OUTPUT);

}

void loop () {
static byte c;

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

}
Title: Re: Reading from Serial
Post by: graynomad on Nov 29, 2011, 05:40 am
Ok for some reason I thought you had a Mega.

Quote
will this still work if i remove the 1 from everything?

No, you'll have to use newSoftSerial. Just replace all the Serial1 stuff with NSS equivalents.

______
Rob


Title: Re: Reading from Serial
Post by: jair2k4 on Nov 29, 2011, 05:56 am
ok check this out and tell me is i messed up. When i send through the console, the light flashes, but no green flickering to indicate that it is receiving.

Am i supposed to be sending on serial and receiving on newsoftserial?

Code: [Select]
#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);
}

}
Title: Re: Reading from Serial
Post by: graynomad on Nov 29, 2011, 06:09 am
Quote
Am i supposed to be sending on serial and receiving on newsoftserial?

Yes.

Quote
When i send through the console,

You're not sending through the console, the code receives from the NSS Rx pin (9?) and sends to the PC. You should see characters on the console.

______
Rob
Title: Re: Reading from Serial
Post by: jair2k4 on Nov 29, 2011, 06:17 am
ok i think i am with you so far, but NSS doesnt pick up anything i send out through the arduino serial monitor. nor does it see anything i echo from the router. Could baud rates be a problem? I would think i would at lease see gibberish pop up in the serial monitor. When i say 'console' i mean monitor, btw. How do i set up NSS to make sure it is seeing pin 8? (should have been 8 to begin with, i have fixed that since.) what would the verbiage be? If i type in #define rxPin 8, will the arduino know enough to associate that with NSS?
Title: Re: Reading from Serial
Post by: graynomad on Nov 29, 2011, 06:32 am
Quote
How do i set up NSS to make sure it is seeing pin 8?

Have a look at the NSS page

http://arduiniana.org/libraries/NewSoftSerial/ (http://arduiniana.org/libraries/NewSoftSerial/)

There must be some documentation there. I've never used NSS but in the constructor

NewSoftSerial mySerial(8,9);

Presumably the 8 and 9 are the Tx and Rx pins (or vice versa).

Quote
but NSS doesnt pick up anything i send out through the arduino serial monitor.

Of course, it's not connected to the PC unless you're running a wire into your laptop :), it's connected to the router.

Quote
nor does it see anything i echo from the router.

You should see something from that if it's transmitting even if the baud rate is wrong (BTW you had 4800 in the original post).

How do you know the router is transmitting anything?

Quote
If i type in #define rxPin 8, will the arduino know enough to associate that with NSS?

Nope, that line at present is doing nothing at all, just defining a more human-readable bit of text. For example

NewSoftSerial mySerial(rxPin,9);

is easier to read than

NewSoftSerial mySerial(8,9);

______
Rob


Title: Re: Reading from Serial
Post by: jair2k4 on Nov 29, 2011, 06:40 am

Quote
Of course, it's not connected to the PC unless you're running a wire into your laptop , it's connected to the router.


But since NSS is handling the receiving end of things, shouldnt it println whatever comes in to it as well as flicker the light? relaying the info taken from the router to the arduino and then printing it out through the hard tx port into the computer? Or is that wrong?

Quote
You should see something from that if it's transmitting even if the baud rate is wrong (BTW you had 4800 in the original post).

How do you know the router is transmitting anything?


I am running:

echo "test' > /dev/tts/1 through the router.

yesterday, i opened up two SSH sessions to the router and ran cat < /dev/tts/1 in one and the echo in the other and it echo'd out to itself through the tx pin and into the rx pin just fine. Its the only test i've been able to find, hence the posting here looking for help.

I should note that i have tried this on 2 different routers with the exact same effect, so it's not my wiring.
Title: Re: Reading from Serial
Post by: graynomad on Nov 29, 2011, 07:18 am
Quote
flicker the light?

What light?

Quote
shouldnt it println whatever comes in

AFIAK the NSS Tx pin is not physically connected to your PC or indeed anything else, how can it transmit to it?

Quote
relaying the info taken from the router to the arduino and then printing it out through the hard tx port into the computer? Or is that wrong?

No that's right, but isn't that what the code is doing? Reading from NSS and writing to Serial.

Quote
and the echo in the other and it echo'd out to itself through the tx pin and into the rx pin just fine.

So you did a physical loopback from a TX pin to an Rx pin, you actually connected an external wire. Is that the case?

If so (and assuming that today the same test still works) then it's reasonable to say there are characters emanating from the router. I'd still like to see it on an instrument though.

Did you figure out the pin 8/9 business. Are you sure you've got the right pin connected?

______
Rob 
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 12:20 am
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.

Code: [Select]
#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);
}

}


Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 01:18 am
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?

Code: [Select]
// 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;           

        }
      }
    }
  }
}




Title: Re: Reading from Serial
Post by: PaulS on Dec 01, 2011, 01:47 am
Code: [Select]
         case '119':
This is almost certainly wrong. Either lose the single quotes, or replace the number in the quotes with the correct letter (preferred).
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 06:13 am
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?

Code: [Select]
// 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;           

        }
      }
    }
  }
}




Title: Re: Reading from Serial
Post by: graynomad on Dec 01, 2011, 06:18 am
Quote
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
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 07:12 am
Basically, something like this....

0
0
0
0
0
0
0

and so on. nothing else.
Title: Re: Reading from Serial
Post by: graynomad on Dec 01, 2011, 07:32 am
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
Title: Re: Reading from Serial
Post by: graynomad on Dec 01, 2011, 07:34 am
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
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 07:41 am
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....
Title: Re: Reading from Serial
Post by: graynomad on Dec 01, 2011, 07:55 am
Quote
I was told by someone (dont know at this point) that the router runs at 115200

Hardly confidence boosting :) You need to know that.

Quote
What's a type constant?

All these

Code: [Select]
#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

Quote
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

Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 08:06 am
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.
Title: Re: Reading from Serial
Post by: graynomad on Dec 01, 2011, 08:13 am
Quote
should i remove swread entirely? as well as the type constants? Just to clean things up?

Yep.

Quote
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
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 01, 2011, 10:16 am
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?

Code: [Select]
// 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;           

        }
      }
    }
  }
}




Title: Re: Reading from Serial
Post by: jair2k4 on Dec 03, 2011, 12:57 am
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

Code: [Select]
// 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;            

       }
     }
   }
 }
}
}
}







(http://i140.photobucket.com/albums/r35/jair2k4/wtf.jpg)
Title: Re: Reading from Serial
Post by: PaulS on Dec 03, 2011, 01:08 am
Quote
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?

Code: [Select]
  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:
Code: [Select]
if (mySerial.available()) {
      serialChar = mySerial.read();


Then you have this:
Code: [Select]
        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.
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 03, 2011, 02:32 am
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.
Title: Re: Reading from Serial
Post by: PaulS on Dec 03, 2011, 04:48 pm
Quote
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.
Title: Re: Reading from Serial
Post by: jair2k4 on Dec 30, 2011, 05:04 am
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?
Title: Re: Reading from Serial
Post by: PaulS on Dec 30, 2011, 07:04 am
Code: [Select]
      serialChar = mySerial.read();
Read a character.

Code: [Select]
      Serial.println(serialChar, HEX);
Echo it.

Code: [Select]
      serialChar = mySerial.read();
Read another character.

Code: [Select]
        switch (serialChar) {
Assume that it is good.

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