Pages: [1]   Go Down
Author Topic: Easy 2 way communication with an Arduino?  (Read 665 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there a library or something similar to make 2 way serial over USB communications easier? Something that will allow to query an Arduino, and it would return values, etc. I understand how to do it manually, just find it very messy. I've searched but haven't found anything that wrapped up that messiness into a library. Is there something out there?
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 986
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, on the Arduino side you might consider Bitlash: http://bitlash.net

There are a lot of options on the PC side, but it really depends on what language you prefer.

For example: Here's a simple serial program uploader and terminal, written in node.js/javascript: https://github.com/billroy/bloader.js

If you prefer python instead: https://github.com/billroy/bloader.py

It might be possible to give a better answer if you said a little more about what you have in mind…

-br
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46113
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is there a library or something similar to make 2 way serial over USB communications easier?
With an understanding of how serial data is transmitted (ssslllooowwwlllyyy), and a knowledge of what needs to be included in a serial data packet (start and end markers, for instance), receiving and sending serial data is dirt simple. I can't imagine why you need a library to complicate your life.

Quote
Something that will allow to query an Arduino
That will allow what to query an Arduino? What kind of questions is the Arduino supposed to be able to answer?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, on the Arduino side you might consider Bitlash: http://bitlash.net
....
It might be possible to give a better answer if you said a little more about what you have in mind…

Bitlash is a good start, though seems much more powerful than what I really need.

I'm thinking of having a sketch with predefined functions, then being able to call those functions by name, pass in a variable or 2 to the function, etc. I'm not having trouble on the host side, the difficulty is on the Arduino side, more specifically parsing the input from the host. I haven't seen good examples of how to do it without any libraries, nor any helper libraries (except Bitlash, now).
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 986
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It sounds like some small user functions in C and you'd be all set.  The tonedemo example might be a good starting point.

It's possible you could even write the functions in bitlash if they are relatively simple and not too time critical.  In which case you could just use the bitlashdemo example and start hacking.

-br
« Last Edit: October 29, 2012, 06:41:54 pm by billroy » Logged

Offline Offline
Edison Member
*
Karma: 18
Posts: 1170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

IF it is not too large, you could create an array of structs:

struct {
char Funcname[32];
void (*Funcptr)(void);
} funcs[32];

And initilise it with all your names and function addresses.
When a function name comes in, just scan the list for a match and then call the function.

But personally, I would use switch/case...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've looked at Bitlash more closely, and there is a limit on the length of function names, which pretty much makes the use of descriptive function names impossible...

But personally, I would use switch/case...

Can you please show an example of such a switch/case setup somewhere?
Logged

Offline Offline
Edison Member
*
Karma: 18
Posts: 1170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually, if/else might be cleaner.

char funcname[64];
int arg1, arg 2, arg 3;
// Parse function that separates function name from arguments
// resulting in
strcpy(funcname, "DoThisFunction");
arg1 = 1;
arg2 = 2;
arg3 = 3;

if (strcmp(funcname, "DoThisFunction") == 0) {
    DoThisFunction(arg1,arg2,arg3);
} else if (strcmp(funcname, "DoThatFunction") == 0) {
   DoThatFunction(arg1, arg2);
} else {
   //oops! No match error handling goes here
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

KeithRB, the part that I find messy is reading the bytes from the serial stream, handling termination characters, etc... is there a complete sketch/example somewhere that will show how to do it?
Logged

Offline Offline
Edison Member
*
Karma: 18
Posts: 1170
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not that I know of, there are so many protocols and ways to parse the data, that it is diffcult to generalize. You might look at sketches that parse GPS NMEA strings for ideas.

If I understand your problem, I would send something like @DoThisFunc(1,2,3)

So your serial routine would wait for a character until it finds an "@", then start fillling a buffer with all the characters it finds until it gets to ")"

Then scan your string and break your string into pieces using the "(" and "," as separators. Do an atoi() on the arguments  and you are done.

There are ways to improve this, but I will leave it up to the interested student.
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 986
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

MikeX: If the function identifier length is the only concern you have about using bitlash, and twelve characters is not enough, you can easily change it to as big a number as you like subject to available ram.  Change the value of IDLEN at line 694 in src/bitlash.h and you should be good to go:

Code:
#define IDLEN 12    // make this bigger if 12 is not enough

Best,

-br
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 986
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For serial port mechanics, you can see how Bitlash assembles a line of text and hands it off to the parser here:

https://github.com/billroy/bitlash/blob/master/src/bitlash-cmdline.c

-br
Logged

DELHI
Offline Offline
God Member
*****
Karma: 0
Posts: 601
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

can some share parse code in c to extract data gps data from gps sensor .

i tried  below code : where i can seprate data but i cant use in other source file

can some share the predefine function that call gps latitude, longitude, date, time, status from RMC data.
provide it support arduino UNO or deumilavo board

or let me know how can extract gps latitude, longitude, date, time, status from RMC data.  through function in same program

#include <string.h>
 #include <ctype.h>
 int ledPin = 13;                  // LED test pin
 int rxPin = 0;                    // RX PIN
 int txPin = 1;                    // TX TX
 int byteGPS=-1;
 char linea[300] = "";
 char comandoGPR[7] = "$GPRMC";
char gps_time[25],gps_status[5],gps_latitude[20],gps_indl[5],gps_longitude[20],gps_indlong[5],gps_NS[10],gps_date[10],gps_head[8],gps_EW[8],gps_mode[5],gps_checksum[8],gps_mag[10];
char *temp;
int varcnt=0;
 int cont=0;
 int bien=0;
 int conta=0;
 int indices[13];
float time,latitude,longitude,date,lat_ind,long_ind,Status;
 
 int k;
 int m;
 void setup() {
   pinMode(ledPin, OUTPUT);       // Initialize LED pin
   pinMode(rxPin, INPUT);
   pinMode(txPin, OUTPUT);
   Serial.begin(9600);
   for (int i=0;i<300;i++){       // Initialize a buffer for received data
     linea=' ';
   }   
 }
 void loop() {
   digitalWrite(ledPin, HIGH);
   byteGPS=Serial.read();         // Read a byte of the serial port
   if (byteGPS == -1) {           // See if the port is empty yet
    // delay(50);
   } else {
     linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer
     conta++;                     
    // Serial.print(byteGPS, BYTE);
     if (byteGPS==13){            // If the received byte is = to 13, end of transmission
       digitalWrite(ledPin, LOW);
       cont=0;
       bien=0;
       for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
         if (linea==comandoGPR[i-1]){
           bien++;
         }
       }
       if(bien==6){               // If yes, continue and process the data
         for (int i=0;i<300;i++){
           if (linea==','){    // check for the position of the  "," separator
             indices[cont]=i;
             cont++;
           
               
           }
           if (linea=='*'){    // ... and the "*"
             indices[12]=i;
             cont++;
           }
         }
         Serial.println("");      // ... and write to the serial port
         Serial.println("");
         Serial.println("---------------");
         for (int i=0;i<12;i++){
           switch(i){
            case 0 :Serial.print("Time in UTC (HhMmSs): ");temp=gps_time;break;
             
            case 1 :Serial.print("Status (A=OK,V=NOT OK): ");temp=gps_status; break;
             case 2 :Serial.print("Latitude: ");temp=gps_latitude; Serial.println("");break;
             case 3 :Serial.print("Direction (N/S): ");temp=gps_indl; Serial.println("");break;
             case 4 :Serial.print("Longitude: ");temp=gps_longitude; Serial.println("");break;
             case 5 :Serial.print("Direction (E/W): ");temp=gps_indlong; Serial.println("");break;
             case 6 :Serial.print("velocity knots: ");temp=gps_NS;break; 
             case 7 :Serial.print("Heading in degrees: ");temp=gps_head;break;
              case 8:Serial.print("Date UTC (DdMmAa): ");temp=gps_date; Serial.println("");break;
               case 9 :Serial.print("Magnetic degrees: ");temp=gps_mag;break;
               case 10 :Serial.print("(E/W): ");temp=gps_EW;break;
               case 11 :Serial.print("Mode: ");temp=gps_mode;break;
                case 12 :Serial.print("Checksum: ");temp=gps_checksum;break;
             
             
                         }
          varcnt=0;
           for (int j=indices;j<(indices[i+1]-1);j++){
             Serial.print(linea[j+1]);
            temp[varcnt]=linea[j+1];
            varcnt++;
               
           
           }             
           
           Serial.println("");
         
           
         }
         Serial.println("");
       
         
         float time=atof(gps_time);
       
         float latitude=atof(gps_latitude);
       
         float longitude=atof(gps_longitude);
       
         float date=atof(gps_date);
         
          Serial.print(time);
          Serial.print(gps_status);
           Serial.print(latitude);
            Serial.print(gps_indl);
             Serial.print(longitude);
              Serial.print(gps_indlong);
               Serial.print(date);
          Serial.print("");
         sprintf(gps_time,"%f",time);
         
         
         
         
         
         
         
            Serial.print("");
         
         Serial.println("---------------");
             
         
       }
       conta=0;                    // Reset the buffer
       for (int i=0;i<300;i++){    // 
         linea=' ';             
       }                 
     }
   }
 }
Logged

AMPS

Pages: [1]   Go Up
Jump to: