NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Listen for serial input

August 20, 2010
by met_fredrik
met_fredrik's Avatar

I am using code similar to the one in the iphone project to send some info with python through serial to the nerdkit. However the numbers I am sending isn't getting through! I think it's something in my microcontroller code that's wrong, but I don't know what!

Here's the code:

int main() {
// output PC1 for relay
DDRC |= (1<<PC1);

// init serial port
uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;

  lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_write_string(PSTR("Doorbell"));

//Boot testing
 PORTC |= (1<<PC1);
  lcd_line_two();
  lcd_write_string(PSTR("Testing."));
    delay_ms(500);
    PORTC &= ~(1<<PC1);

  int kode;
  int16_t result;
  while(1) {
// listen for bytes
result = scanf_P(PSTR("%d"), &kode);
if(result == 1) {

  // Got command!
  if(kode=='4') 
  {
  lcd_line_two();
  lcd_write_string(PSTR("Riktig kode."));

//opening port  
    PORTC |= (1<<PC1);

//delay for 15 seconds so I get time to get inside
    delay_ms(15000);

    //turn off relay
            PORTC &= ~(1<<PC1);
      }
      else {
      lcd_line_two();
      lcd_write_string(PSTR("Ugyldig kode."));
    }

  } 
}
  return 0;
}

I didn't paste the includes etc. The code compiles just fine, but something has to be wrong!

And the python script runs without any errors and outputs the right numbers in terminal. But here's the python code aswell:

import serial

s = serial.Serial("/dev/ttyUSB0", 115200)

def sendCode(command):
try:
    (x) = command
    s.write (str(int(x)))
    print (str(int(x)))
except:
    print "Error occurred. Ignore and move on"

while(True):
tePipe = open('/pipe/door', 'r')
sendCode(tePipe.read());
tePipe.close()

Would be really happy if someone could look through my code! Thanks! :D

August 20, 2010
by hevans
(NerdKits Staff)

hevans's Avatar

Hi met_fredrik,

I think I see one problem with your code which is causing your issue. On line 26 of your code you have

int kode;

and then you correctly use scanf to read the number into your kode variable.

result = scanf_P(PSTR("%d"), &kode);

The thing to note is that you are using the %d string format operation, which is going to look for an integer and then dump it into an integer variable. If you sent 4 at this point the kode variable is the number 4. Then you try to compare against this variable in an if statement but you put the 4 in single quotes.

if(kode=='4') {

}

The if statement will only be true if kode is equal to the character 4, not the integer 4; so this if statement is not true with the number 4 (try sending the number 52 over the serial port, see what happens).

Try comparing against the number 4, and let us know if it works. Can't wait to see your key code door system in action!

Humberto

August 21, 2010
by met_fredrik
met_fredrik's Avatar

Thanks for your quick answer! You pointed out one of the problems with my code. The other however, making the mcu not receiving the serial commands I haven't solved. So I switched some code, now using this instead:

tc = uart_read();

if(tc=='8') {

lcd_line_two();
  lcd_write_string(P......................

The uart_read captures everything I send. But still I am on the variable problem. I did as you told me and got rid of the ' around the number. And it worked, however I want to work with larger numbers. And the numbers are sent one by one it seems. So if I try to read the tc variable as something larger than 9 it won't work. So what am I doing wrong here? :D

int tc;
 while(1) {

tc = uart_read();

if(tc=='8') {

lcd_line_two();
    lcd_write_string(PSTR("Riktig kode. Opening door."));

//opening port  
    PORTC |= (1<<PC1);

   //delay for 15 seconds so I get time to get inside
    delay_ms(5000);
    lcd_line_two();
    lcd_write_string(PSTR("Venter på input..."));

   //turn off relay
    PORTC &= ~(1<<PC1);
   }

else {
  lcd_line_two();
  fprintf_P(&lcd_stream, PSTR("Ugyldig  %c "), tc);
  delay_ms(1000);
  lcd_line_two();
  lcd_write_string(PSTR("Venter på input..."));
  }
August 24, 2010
by mrobbins
(NerdKits Staff)

mrobbins's Avatar

Hi met_fredrik,

In your original scanf_P based serial reading, I am curious as to whether you ever write a newline character (or other whitespace) that tells scanf_P that you're done with a particular number. For example, in your Python code from your very first message, change:

s.write (str(int(x)))
print (str(int(x)))

to:

s.write(str(int(x)))
s.write("\n")
print (str(int(x)))

That way, the newline character will get sent, so scanf_P knows to stop reading characters. As per the scanf documentation, "Processing is aborted as soon as the data and format string no longer match, or there is an error or end-of-file condition on stream." Without having a newline or space or similar, the scanf_P will just see a stream of ASCII digits coming in, and may never exit.

Mike

Post a Reply

Please log in to post a reply.

Did you know that the printf format string "%.3f" will show three digits after the decimal point? Learn more...