Go Down

Topic: Blink example only works when the serial monitor is ON (Read 1 time) previous topic - next topic

quadro

Mar 30, 2011, 02:41 pm Last Edit: Mar 30, 2011, 02:57 pm by quadro Reason: 1
Hi
I am running ubuntu, and these are the codes i am currently using:
My problem is that the LED reacts (flickers) when i send a message to the arduino using the first code below, but it does not produce the expected results.The LED should blink as many times as the number i sent to the arduino instead it only flickers when i send the number to it and does nothing else. BUT when the serial monitor is on, i works correctly...

Yes i have the correct baud
yes i have uploaded the code on the arduino =P
I am new in this subject so any help is appreciated!

ALL CODES ARE COPIED FROM AN ONLINE TUTORIAL

Code: [Select]
[code]/*
* Arduino-serial
* --------------
*
* A simple command-line example program showing how a computer can
* communicate with an Arduino board. Works on any POSIX system (Mac/Unix/PC)
*
*
* Compile with something like:
* gcc -o arduino-serial arduino-serial.c
*
* Created 5 December 2006
* Copyleft (c) 2006, Tod E. Kurt, tod@todbot.com
* http://todbot.com/blog/
*
*
* Updated 8 December 2006:
*  Justin McBride discoevered B14400 & B28800 aren't in Linux's termios.h.
*  I've included his patch, but commented out for now.  One really needs a
*  real make system when doing cross-platform C and I wanted to avoid that
*  for this little program. Those baudrates aren't used much anyway. :)
*
* Updated 26 December 2007:
*  Added ability to specify a delay (so you can wait for Arduino Diecimila)
*  Added ability to send a binary byte number
*
* Update 31 August 2008:
*  Added patch to clean up odd baudrates from Andy at hexapodia.org
*
*/

#include <stdio.h>    /* Standard input/output definitions */
#include <stdlib.h>
#include <stdint.h>   /* Standard types */
#include <string.h>   /* String function definitions */
#include <unistd.h>   /* UNIX standard function definitions */
#include <fcntl.h>    /* File control definitions */
#include <errno.h>    /* Error number definitions */
#include <termios.h>  /* POSIX terminal control definitions */
#include <sys/ioctl.h>
#include <getopt.h>

void usage(void);
int serialport_init(const char* serialport, int baud);
int serialport_writebyte(int fd, uint8_t b);
int serialport_write(int fd, const char* str);
int serialport_read_until(int fd, char* buf, char until);

void usage(void) {
   printf("Usage: arduino-serial -p <serialport> [OPTIONS]\n"
   "\n"
   "Options:\n"
   "  -h, --help                   Print this help message\n"
   "  -p, --port=serialport        Serial port Arduino is on\n"
   "  -b, --baud=baudrate          Baudrate (bps) of Arduino\n"
   "  -s, --send=data              Send data to Arduino\n"
   "  -r, --receive                Receive data from Arduino & print it out\n"
   "  -n  --num=num                Send a number as a single byte\n"
   "  -d  --delay=millis           Delay for specified milliseconds\n"
   "\n"
   "Note: Order is important. Set '-b' before doing '-p'. \n"
   "      Used to make series of actions:  '-d 2000 -s hello -d 100 -r' \n"
   "      means 'wait 2secs, send 'hello', wait 100msec, get reply'\n"
   "\n");
}

int main(int argc, char *argv[])
{
   int fd = 0;
   char serialport[256];
   int baudrate = B9600;  // default
   char buf[256];
   int rc,n;

   if (argc==1) {
       usage();
       exit(EXIT_SUCCESS);
   }

   /* parse options */
   int option_index = 0, opt;
   static struct option loptions[] = {
       {"help",       no_argument,       0, 'h'},
       {"port",       required_argument, 0, 'p'},
       {"baud",       required_argument, 0, 'b'},
       {"send",       required_argument, 0, 's'},
       {"receive",    no_argument,       0, 'r'},
       {"num",        required_argument, 0, 'n'},
       {"delay",      required_argument, 0, 'd'}
   };
   
   while(1) {
       opt = getopt_long (argc, argv, "hp:b:s:rn:d:",
                          loptions, &option_index);
       if (opt==-1) break;
       switch (opt) {
       case '0': break;
       case 'd':
           n = strtol(optarg,NULL,10);
           usleep(n * 1000 ); // sleep milliseconds
           break;
       case 'h':
           usage();
           break;
       case 'b':
           baudrate = strtol(optarg,NULL,10);
           break;
       case 'p':
           strcpy(serialport,optarg);
           fd = serialport_init(optarg, baudrate);
           if(fd==-1) return -1;
           break;
       case 'n':
           n = strtol(optarg, NULL, 10); // convert string to number
           rc = serialport_writebyte(fd, (uint8_t)n);
           if(rc==-1) return -1;
           break;
       case 's':
           strcpy(buf,optarg);
           rc = serialport_write(fd, buf);
           if(rc==-1) return -1;
           break;
       case 'r':
           serialport_read_until(fd, buf, '\n');
           printf("read: %s\n",buf);
           break;
       }
   }

   exit(EXIT_SUCCESS);    
} // end main
   
int serialport_writebyte( int fd, uint8_t b)
{
   int n = write(fd,&b,1);
   if( n!=1)
       return -1;
   return 0;
}

int serialport_write(int fd, const char* str)
{
   int len = strlen(str);
   int n = write(fd, str, len);
   if( n!=len )
       return -1;
   return 0;
}

int serialport_read_until(int fd, char* buf, char until)
{
   char b[1];
   int i=0;
   do {
       int n = read(fd, b, 1);  // read a char at a time
       if( n==-1) return -1;    // couldn't read
       if( n==0 ) {
           usleep( 10 * 1000 ); // wait 10 msec try again
           continue;
       }
       buf[i] = b[0]; i++;
   } while( b[0] != until );

   buf[i] = 0;  // null terminate the string
   return 0;
}

// takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1")
// and a baud rate (bps) and connects to that port at that speed and 8N1.
// opens the port in fully raw mode so you can send binary data.
// returns valid fd, or -1 on error
int serialport_init(const char* serialport, int baud)
{
   struct termios toptions;
   int fd;
   
   //fprintf(stderr,"init_serialport: opening port %s @ %d bps\n",
   //        serialport,baud);

   fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
   if (fd == -1)  {
       perror("init_serialport: Unable to open port ");
       return -1;
   }
   
   if (tcgetattr(fd, &toptions) < 0) {
       perror("init_serialport: Couldn't get term attributes");
       return -1;
   }
   speed_t brate = baud; // let you override switch below if needed
   switch(baud) {
   case 4800:   brate=B4800;   break;
   case 9600:   brate=B9600;   break;
#ifdef B14400
   case 14400:  brate=B14400;  break;
#endif
   case 19200:  brate=B19200;  break;
#ifdef B28800
   case 28800:  brate=B28800;  break;
#endif
   case 38400:  brate=B38400;  break;
   case 57600:  brate=B57600;  break;
   case 115200: brate=B115200; break;
   }
   cfsetispeed(&toptions, brate);
   cfsetospeed(&toptions, brate);

   // 8N1
   toptions.c_cflag &= ~PARENB;
   toptions.c_cflag &= ~CSTOPB;
   toptions.c_cflag &= ~CSIZE;
   toptions.c_cflag |= CS8;
   // no flow control
   toptions.c_cflag &= ~CRTSCTS;

   toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
   toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl

   toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
   toptions.c_oflag &= ~OPOST; // make raw

   // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
   toptions.c_cc[VMIN]  = 0;
   toptions.c_cc[VTIME] = 20;
   
   if( tcsetattr(fd, TCSANOW, &toptions) < 0) {
       perror("init_serialport: Couldn't set term attributes");
       return -1;
   }

   return fd;
}
[/code]

the second code


Code: [Select]
/*
* Serial Read Blink
* -----------------
* Turns on and off a light emitting diode(LED) connected to digital  
* pin 13. The LED will blink the number of times given by a
* single-digit ASCII number read from the serial port.
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com>
* http://todbot.com/
*
* based on "serial_read_advanced" example
*/

int ledPin = 13;   // select the pin for the LED
int val = 0;       // variable to store the data from the serial port

void setup() {
 pinMode(ledPin,OUTPUT);    // declare the LED's pin as output
 Serial.begin(9600);        // connect to the serial port
}

void loop () {
 val = Serial.read();      // read the serial port

 // if the stored value is a single-digit number, blink the LED that number
 if (val > '0' && val <= '9' ) {
   val = val - '0';          // convert from character to number
   for(int i=0; i<val; i++) {
     Serial.println("blink!");
     digitalWrite(ledPin,HIGH);
     delay(150);
     digitalWrite(ledPin, LOW);
     delay(150);
   }
   //Serial.println();
 }
}


Grumpy_Mike

#1
Mar 30, 2011, 02:48 pm Last Edit: Mar 30, 2011, 03:04 pm by Grumpy_Mike Reason: 1
Thanks for modifying, I am looking at it now.


Grumpy_Mike

There is nothing wrong I can see with the arduino side.
Have you tried just driving this from the serial monitor? It should work.

However it looks like the other side is the one that is not working. If it only works when the serial monitor is open it looks like it is not opening the serial ports correctly. In fact it shouldn't work when the serial monitor is on because then you have two applications accessing the same hardware.
Unfortunately  I don't have the language you have but it appears not to be working properly.

quadro

When i press the serial monitor button in arduino ide and then run the c Code from the comandline it then blinks as intended, i dont understand why.

Grumpy_Mike

Quote
i dont understand why.

It is because your C code is not opening the serial port. I can see no instructions where this is supposed to happen. Look into this language a bit further and find out how to open the serial port.

quadro

But the thing is, when i send a number using the C code to the arduino, comandline, the arduino LED flickers, so there should not be a problem in the port? or am i wrong...remember im a complete noob in arduino =)!

Grumpy_Mike

When you run the code from the command line exactly what are you entering?
You could get the same effect if the port was opening but the baud rate was wrong. It is looking like the arduino's serial monitor is configuring the serial port correctly where as your code is not. By the way I can't see where the baud rate is initialised in the code.

quadro

In the comandline i enter the (-b 9600) which is the baude and the (-s 3) where we send the number 3 to the arduino. =(

Grumpy_Mike



quadro

-p is the port /dev/ttyAMC0


@senso, where do u see serial.avaliable ????


Grumpy_Mike

What senso is saying is that you just do
val = Serial.read(); 
In the arduino code without testing if there is actually data in the serial buffer to read. This is done by a call to Serial.available();
You don't have this.
However due to the way the code is written it won't matter in your case.

Why will you not answer questions? I asked:-
Quote
When you run the code from the command line exactly what are you entering?

And I have to drag it out of you. Quite simply the C code is not working and this is either something wrong in the code, the installation or what you are doing. I am trying to find out what you are doing but you are making it hard. The point is that you code is not communicating with the serial port correctly.

quadro

This what i enter in the comandline
./serial -b 9600 -p /dev/ttyACM0 -s 2

-s writes the number 2 to the port specified above.

Go Up