Difference between revisions of "Arduino loop"
(→arduino-loop.pde) |
(→arduino-loop.pde) |
||
(7 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
__TOC__ | __TOC__ | ||
+ | |||
+ | =talkToArduino.asm= | ||
+ | <code><pre> | ||
+ | ;;; talkToArduino.asm | ||
+ | ;;; D. Thiebaut | ||
+ | ;;; | ||
+ | ;;; nasm -f elf talkToArduino.asm | ||
+ | ;;; gcc -o talkToArduino arduino-serial.c talkToArduino.o | ||
+ | ;;; | ||
+ | |||
+ | ;;; ----------------------- EXTERN LABELS ----------------------- | ||
+ | extern serialport_writebyte ; int function | ||
+ | extern serialport_write ; int function | ||
+ | extern serialport_read_until ; int function | ||
+ | extern displayBuffer ; int function | ||
+ | |||
+ | extern buf | ||
+ | extern byte | ||
+ | |||
+ | ;; ------------------------- | ||
+ | ;; data segment | ||
+ | ;; ------------------------- | ||
+ | section .data | ||
+ | msg1 db "w d 13 1", 0 | ||
+ | msg1len equ $-msg1 | ||
+ | |||
+ | msg2 db "w d 13 0", 0 | ||
+ | msg2len equ $-msg2 | ||
+ | |||
+ | msg3 db "r d", 0 | ||
+ | msg3len equ $-msg3 | ||
+ | |||
+ | msg4 db "w d 13 " | ||
+ | msg4val db '?', 0 | ||
+ | msg4len equ $-msg4 | ||
+ | |||
+ | section .bss | ||
+ | |||
+ | ;; ------------------------- | ||
+ | ;; code area | ||
+ | ;; ------------------------- | ||
+ | section .text | ||
+ | global asm_main | ||
+ | asm_main: | ||
+ | |||
+ | ;; turn Pin 13 On/Off a few times | ||
+ | mov eax, msg1 | ||
+ | mov ecx, msg1len | ||
+ | call copyMsg | ||
+ | call serialport_write | ||
+ | |||
+ | call delay100ms | ||
+ | |||
+ | mov eax, msg2 | ||
+ | mov ecx, msg2len | ||
+ | call copyMsg | ||
+ | call serialport_write | ||
+ | |||
+ | call delay100ms | ||
+ | |||
+ | mov eax, msg1 | ||
+ | mov ecx, msg1len | ||
+ | call copyMsg | ||
+ | call serialport_write | ||
+ | |||
+ | call delay100ms | ||
+ | |||
+ | mov eax, msg2 | ||
+ | mov ecx, msg2len | ||
+ | call copyMsg | ||
+ | call serialport_write | ||
+ | |||
+ | .for mov ecx, 1000 ; read/write switch 1000 times | ||
+ | call readPin2 ; get status of Pin 2 in al | ||
+ | call setPin13 ; set Pin 13 to value in al | ||
+ | loop .for | ||
+ | |||
+ | ;; return to C program | ||
+ | |||
+ | ret | ||
+ | |||
+ | ;;; ---------------------------------------------------------------- | ||
+ | ;;; copyMsg1: puts array whose address in eax in external buffer | ||
+ | ;;; number of bytes shoudl be in ecx. | ||
+ | ;;; ---------------------------------------------------------------- | ||
+ | copyMsg: | ||
+ | pushad | ||
+ | mov esi, eax ; source buffer | ||
+ | mov edi, buf ; destination buffer in C program | ||
+ | .for mov al, [esi] | ||
+ | mov [edi], al | ||
+ | inc esi | ||
+ | inc edi | ||
+ | loop .for | ||
+ | popad | ||
+ | ret | ||
+ | |||
+ | ;;; ---------------------------------------------------------------- | ||
+ | ;;; delay 100 ms. | ||
+ | ;;; ---------------------------------------------------------------- | ||
+ | delay100ms: | ||
+ | pushad | ||
+ | mov ecx, 100000000 ; 200,000,000 cycles (assuming 2GHz) | ||
+ | .for add eax, 1 ; 1 cycle | ||
+ | loop .for ; 1 cycle | ||
+ | popad | ||
+ | ret | ||
+ | |||
+ | ;;; ---------------------------------------------------------------- | ||
+ | ;;; readPin2: sends the arduino a request for value of pins | ||
+ | ;;; returns '0' or '1' in al as value of Pin 2 | ||
+ | ;;; ---------------------------------------------------------------- | ||
+ | readPin2: | ||
+ | mov eax, msg3 | ||
+ | mov ecx, msg3len ; "r d" read digital pins | ||
+ | call copyMsg ; now buf contains "r d" | ||
+ | call serialport_write | ||
+ | |||
+ | call serialport_read_until | ||
+ | ;;; call displayBuffer | ||
+ | |||
+ | ;;; get the value of input pin 2 as defined in buffer | ||
+ | ;;; which contains "d 0 0 1 0 0 0 1 0 0 0 0 0" | ||
+ | ;;; and first 0 is Pin 2, second 0 is Pin 3, etc. | ||
+ | |||
+ | mov al, [buf+2] ; get first digit and put it | ||
+ | ; in al | ||
+ | ret | ||
+ | |||
+ | ;;; ---------------------------------------------------------------- | ||
+ | ;;; SetPin13: sets pin 13 to the value '0' or '1' passed in al | ||
+ | ;;; ---------------------------------------------------------------- | ||
+ | setPin13: | ||
+ | pushad | ||
+ | mov [msg4val],al ; and embed '0' or '1' at right place | ||
+ | mov eax, msg4 | ||
+ | mov ecx, msg4len ; copy msg4 in buf | ||
+ | call copyMsg | ||
+ | ;;; call displayBuffer | ||
+ | call serialport_write; send message "w d 13 x" to arduino | ||
+ | popad ; restore registers | ||
+ | |||
+ | ret | ||
+ | |||
+ | </pre></code> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | [[Category:CSC231]][[Category:Arduino]] | ||
=arduino-serial.c= | =arduino-serial.c= | ||
Line 14: | Line 163: | ||
* A simple command-line example program showing how a computer can | * A simple command-line example program showing how a computer can | ||
* communicate with an Arduino board. Works on any POSIX system (Mac/Unix/PC) | * communicate with an Arduino board. Works on any POSIX system (Mac/Unix/PC) | ||
− | * | + | * |
* | * | ||
* Compile with something like: | * Compile with something like: | ||
Line 37: | Line 186: | ||
* Added patch to clean up odd baudrates from Andy at hexapodia.org | * Added patch to clean up odd baudrates from Andy at hexapodia.org | ||
* | * | ||
+ | * Modified 11/06/08 by D. Thiebaut | ||
+ | * Force program to wait until a \n is received from Arduino | ||
+ | * Added linking with assembly program | ||
*/ | */ | ||
Line 50: | Line 202: | ||
#include <getopt.h> | #include <getopt.h> | ||
+ | extern int asm_main( void ); | ||
+ | |||
+ | //-------------------------- prototypes --------------------------- | ||
void usage(void); | void usage(void); | ||
int serialport_init(const char* serialport, int baud); | int serialport_init(const char* serialport, int baud); | ||
− | int serialport_writebyte( | + | int serialport_writebyte( ); |
− | int serialport_write(int | + | int serialport_write( ); |
− | int | + | int serialport_read_until( ); |
+ | int displayBuffer( ); | ||
+ | |||
+ | //---------------------------- globals ---------------------------- | ||
+ | int fd = 0; // file descriptor for USB device | ||
+ | char serialport[256]; // name of the serial port (/dev/ttyUSB0) | ||
+ | int baudrate = B9600; // default baud rate | ||
+ | char buf[1024]; // buffer for sent/receive strings | ||
+ | uint8_t byte; | ||
+ | int pin; | ||
+ | //----------------------------------------------------------------- | ||
+ | //----------------------------------------------------------------- | ||
void usage(void) { | void usage(void) { | ||
printf("Usage: arduino-serial -p <serialport> [OPTIONS]\n" | printf("Usage: arduino-serial -p <serialport> [OPTIONS]\n" | ||
Line 74: | Line 240: | ||
} | } | ||
− | int main(int argc, char *argv[]) | + | //----------------------------------------------------------------- |
− | { | + | int main(int argc, char *argv[]) { |
− | + | int rc, n; | |
− | |||
− | |||
− | |||
− | int rc,n; | ||
if (argc==1) { | if (argc==1) { | ||
Line 87: | Line 249: | ||
} | } | ||
− | /* parse options */ | + | /*--- parse options ---*/ |
int option_index = 0, opt; | int option_index = 0, opt; | ||
static struct option loptions[] = { | static struct option loptions[] = { | ||
Line 99: | Line 261: | ||
}; | }; | ||
+ | /*--- process the command line arguments ---*/ | ||
while(1) { | while(1) { | ||
− | opt = getopt_long (argc, argv, "hp:b:s:rn:d:", | + | opt = getopt_long ( argc, argv, "hp:b:s:rn:d:", |
− | loptions, &option_index); | + | loptions, &option_index ); |
if (opt==-1) break; | if (opt==-1) break; | ||
switch (opt) { | switch (opt) { | ||
Line 117: | Line 280: | ||
case 'p': | case 'p': | ||
strcpy(serialport,optarg); | strcpy(serialport,optarg); | ||
− | fd = serialport_init(optarg, baudrate); | + | fd = serialport_init( optarg, baudrate ); |
if(fd==-1){ | if(fd==-1){ | ||
printf( "Could not initialize USB port\n\n" ); | printf( "Could not initialize USB port\n\n" ); | ||
Line 124: | Line 287: | ||
break; | break; | ||
case 'n': | case 'n': | ||
− | n = strtol(optarg, NULL, 10); // convert string to number | + | n = strtol(optarg, NULL, 10 ); // convert string to number |
− | rc = serialport_writebyte( | + | byte = (uint8_t) n; |
+ | rc = serialport_writebyte( ); | ||
if(rc==-1) return -1; | if(rc==-1) return -1; | ||
break; | break; | ||
case 's': | case 's': | ||
− | strcpy(buf,optarg); | + | strcpy( buf, optarg ); |
− | rc = serialport_write( | + | rc = serialport_write( ); |
− | if(rc==-1) return -1; | + | if (rc==-1) return -1; |
break; | break; | ||
case 'r': | case 'r': | ||
− | + | serialport_read_until( ); | |
− | printf(" | + | printf("%s\n",buf); |
break; | break; | ||
} | } | ||
} | } | ||
+ | //--- call assembly language program --- | ||
+ | asm_main(); | ||
+ | |||
+ | //--- exit --- | ||
exit(EXIT_SUCCESS); | exit(EXIT_SUCCESS); | ||
+ | |||
} // end main | } // end main | ||
− | int | + | //----------------------------------------------------------------- |
− | { | + | //----------------------------------------------------------------- |
− | int n = write(fd,& | + | int displayBuffer( ) { |
+ | printf( "buffer = [%s]\n", buf ); | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | //----------------------------------------------------------------- | ||
+ | //----------------------------------------------------------------- | ||
+ | int serialport_writebyte( ) { | ||
+ | int n = write( fd, &byte, 1); | ||
if( n!=1) | if( n!=1) | ||
return -1; | return -1; | ||
Line 151: | Line 328: | ||
} | } | ||
− | int serialport_write( | + | //----------------------------------------------------------------- |
+ | //----------------------------------------------------------------- | ||
+ | int serialport_write() { | ||
int len; | int len; | ||
− | + | strcat( buf, "\n" ); | |
− | + | len = strlen(buf); | |
− | strcat( | + | int n = write( fd, buf, len ); |
− | len = strlen( | + | |
− | int n = write(fd, | ||
if( n!=len ) | if( n!=len ) | ||
return -1; | return -1; | ||
Line 163: | Line 341: | ||
} | } | ||
− | int serialport_read_until( | + | //----------------------------------------------------------------- |
+ | //----------------------------------------------------------------- | ||
+ | int serialport_read_until( ) { | ||
char b[1]; | char b[1]; | ||
int i=0, k; | int i=0, k; | ||
Line 178: | Line 358: | ||
buf[i] = b[0]; | buf[i] = b[0]; | ||
i++; | i++; | ||
− | } while( b[0] != | + | } while( b[0] != '\n' ); |
buf[i] = 0; // null terminate the string | buf[i] = 0; // null terminate the string | ||
Line 184: | Line 364: | ||
} | } | ||
+ | //----------------------------------------------------------------- | ||
// takes the string name of the serial port (e.g. "/dev/tty.usbserial","COM1") | // 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. | // 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. | // opens the port in fully raw mode so you can send binary data. | ||
// returns valid fd, or -1 on error | // returns valid fd, or -1 on error | ||
+ | //----------------------------------------------------------------- | ||
int serialport_init(const char* serialport, int baud) | int serialport_init(const char* serialport, int baud) | ||
{ | { | ||
Line 210: | Line 392: | ||
case 4800: brate=B4800; break; | case 4800: brate=B4800; break; | ||
case 9600: brate=B9600; break; | case 9600: brate=B9600; break; | ||
− | #ifdef B14400 | + | #ifdef B14400 |
case 14400: brate=B14400; break; | case 14400: brate=B14400; break; | ||
− | #endif | + | #endif |
case 19200: brate=B19200; break; | case 19200: brate=B19200; break; | ||
− | #ifdef B28800 | + | #ifdef B28800 |
case 28800: brate=B28800; break; | case 28800: brate=B28800; break; | ||
− | #endif | + | #endif |
case 38400: brate=B38400; break; | case 38400: brate=B38400; break; | ||
case 57600: brate=B57600; break; | case 57600: brate=B57600; break; | ||
Line 229: | Line 411: | ||
toptions.c_cflag &= ~CSIZE; | toptions.c_cflag &= ~CSIZE; | ||
toptions.c_cflag |= CS8; | toptions.c_cflag |= CS8; | ||
+ | |||
// no flow control | // no flow control | ||
toptions.c_cflag &= ~CRTSCTS; | toptions.c_cflag &= ~CRTSCTS; | ||
Line 249: | Line 432: | ||
return fd; | return fd; | ||
} | } | ||
− | |||
Line 257: | Line 439: | ||
<code><pre> | <code><pre> | ||
− | + | // | |
− | // | ||
// arduino-loop.pde | // arduino-loop.pde | ||
// 11/6/08 | // 11/6/08 | ||
− | // | + | // V. 5 |
// ------------------------------------------------------------- | // ------------------------------------------------------------- | ||
Line 315: | Line 496: | ||
Serial.println( "Error" ); | Serial.println( "Error" ); | ||
} | } | ||
− | |||
resetAll(); | resetAll(); | ||
return; | return; | ||
Line 425: | Line 605: | ||
if ( mode=='a' ) | if ( mode=='a' ) | ||
analogWrite( intPin, intState ); | analogWrite( intPin, intState ); | ||
+ | //delay( 50 ); // 0.05 sec | ||
+ | //Serial.println( "OK" ); | ||
return 0; | return 0; | ||
} | } | ||
Line 451: | Line 633: | ||
return 0; | return 0; | ||
} | } | ||
+ | |||
</pre></code> | </pre></code> | ||
+ | <br /> | ||
+ | |||
+ | <br /> | ||
+ | |||
+ | <br /> | ||
+ | |||
+ | <br /> | ||
+ | |||
+ | <br /> | ||
+ | |||
+ | <br /> | ||
+ | [[Category:CSC231]][[Category:Arduino]][[Category:C]] |
Latest revision as of 12:39, 9 October 2010
--D. Thiebaut 17:08, 1 November 2008 (UTC)
Status: could make arduino-serial.c program send commands and read from Arduino
talkToArduino.asm
;;; talkToArduino.asm
;;; D. Thiebaut
;;;
;;; nasm -f elf talkToArduino.asm
;;; gcc -o talkToArduino arduino-serial.c talkToArduino.o
;;;
;;; ----------------------- EXTERN LABELS -----------------------
extern serialport_writebyte ; int function
extern serialport_write ; int function
extern serialport_read_until ; int function
extern displayBuffer ; int function
extern buf
extern byte
;; -------------------------
;; data segment
;; -------------------------
section .data
msg1 db "w d 13 1", 0
msg1len equ $-msg1
msg2 db "w d 13 0", 0
msg2len equ $-msg2
msg3 db "r d", 0
msg3len equ $-msg3
msg4 db "w d 13 "
msg4val db '?', 0
msg4len equ $-msg4
section .bss
;; -------------------------
;; code area
;; -------------------------
section .text
global asm_main
asm_main:
;; turn Pin 13 On/Off a few times
mov eax, msg1
mov ecx, msg1len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg2
mov ecx, msg2len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg1
mov ecx, msg1len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg2
mov ecx, msg2len
call copyMsg
call serialport_write
.for mov ecx, 1000 ; read/write switch 1000 times
call readPin2 ; get status of Pin 2 in al
call setPin13 ; set Pin 13 to value in al
loop .for
;; return to C program
ret
;;; ----------------------------------------------------------------
;;; copyMsg1: puts array whose address in eax in external buffer
;;; number of bytes shoudl be in ecx.
;;; ----------------------------------------------------------------
copyMsg:
pushad
mov esi, eax ; source buffer
mov edi, buf ; destination buffer in C program
.for mov al, [esi]
mov [edi], al
inc esi
inc edi
loop .for
popad
ret
;;; ----------------------------------------------------------------
;;; delay 100 ms.
;;; ----------------------------------------------------------------
delay100ms:
pushad
mov ecx, 100000000 ; 200,000,000 cycles (assuming 2GHz)
.for add eax, 1 ; 1 cycle
loop .for ; 1 cycle
popad
ret
;;; ----------------------------------------------------------------
;;; readPin2: sends the arduino a request for value of pins
;;; returns '0' or '1' in al as value of Pin 2
;;; ----------------------------------------------------------------
readPin2:
mov eax, msg3
mov ecx, msg3len ; "r d" read digital pins
call copyMsg ; now buf contains "r d"
call serialport_write
call serialport_read_until
;;; call displayBuffer
;;; get the value of input pin 2 as defined in buffer
;;; which contains "d 0 0 1 0 0 0 1 0 0 0 0 0"
;;; and first 0 is Pin 2, second 0 is Pin 3, etc.
mov al, [buf+2] ; get first digit and put it
; in al
ret
;;; ----------------------------------------------------------------
;;; SetPin13: sets pin 13 to the value '0' or '1' passed in al
;;; ----------------------------------------------------------------
setPin13:
pushad
mov [msg4val],al ; and embed '0' or '1' at right place
mov eax, msg4
mov ecx, msg4len ; copy msg4 in buf
call copyMsg
;;; call displayBuffer
call serialport_write; send message "w d 13 x" to arduino
popad ; restore registers
ret
arduino-serial.c
/*
* 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
*
* Modified 11/06/08 by D. Thiebaut
* Force program to wait until a \n is received from Arduino
* Added linking with assembly program
*/
#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>
extern int asm_main( void );
//-------------------------- prototypes ---------------------------
void usage(void);
int serialport_init(const char* serialport, int baud);
int serialport_writebyte( );
int serialport_write( );
int serialport_read_until( );
int displayBuffer( );
//---------------------------- globals ----------------------------
int fd = 0; // file descriptor for USB device
char serialport[256]; // name of the serial port (/dev/ttyUSB0)
int baudrate = B9600; // default baud rate
char buf[1024]; // buffer for sent/receive strings
uint8_t byte;
int pin;
//-----------------------------------------------------------------
//-----------------------------------------------------------------
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 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'}
};
/*--- process the command line arguments ---*/
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){
printf( "Could not initialize USB port\n\n" );
return -1;
}
break;
case 'n':
n = strtol(optarg, NULL, 10 ); // convert string to number
byte = (uint8_t) n;
rc = serialport_writebyte( );
if(rc==-1) return -1;
break;
case 's':
strcpy( buf, optarg );
rc = serialport_write( );
if (rc==-1) return -1;
break;
case 'r':
serialport_read_until( );
printf("%s\n",buf);
break;
}
}
//--- call assembly language program ---
asm_main();
//--- exit ---
exit(EXIT_SUCCESS);
} // end main
//-----------------------------------------------------------------
//-----------------------------------------------------------------
int displayBuffer( ) {
printf( "buffer = [%s]\n", buf );
return 0;
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
int serialport_writebyte( ) {
int n = write( fd, &byte, 1);
if( n!=1)
return -1;
return 0;
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
int serialport_write() {
int len;
strcat( buf, "\n" );
len = strlen(buf);
int n = write( fd, buf, len );
if( n!=len )
return -1;
return 0;
}
//-----------------------------------------------------------------
//-----------------------------------------------------------------
int serialport_read_until( ) {
char b[1];
int i=0, k;
do {
int n = read(fd, b, 1); // read a char at a time
if( n==-1) {
usleep( 100*1000 );
continue;
}
if( n==0 ) {
usleep( 10 * 1000 ); // wait 10 msec try again
continue;
}
buf[i] = b[0];
i++;
} while( b[0] != '\n' );
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;
}
arduino-loop.pde
//
// arduino-loop.pde
// 11/6/08
// V. 5
// -------------------------------------------------------------
// GLOBALS
// -------------------------------------------------------------
char buffer[256];
int len;
char *operation;
char *mode;
char *pin;
char *state;
// -------------------------------------------------------------
// PROTOTYPES
// -------------------------------------------------------------
void resetAll();
int process();
int writePin( char mode, int pin, int state );
int readPins( char mode );
// -------------------------------------------------------------
// SETUP: initializes port and buffer
// -------------------------------------------------------------
void setup() {
Serial.begin(9600);
resetAll();
}
// -------------------------------------------------------------
// RESETALL: clears the buffer and the globals
// -------------------------------------------------------------
void resetAll() {
buffer[0] = '\0';
len = 0;
operation = mode = pin = state = 0;
}
// -------------------------------------------------------------
// LOOP: main workhorse. Called repeatedly. Gets chars from
// the arduino, and processes it when \n received
// -------------------------------------------------------------
void loop() {
int c;
c = Serial.read();
// nothing received, nothing to do
if (c==-1) return;
// \n terminator received, process message
if ( c=='\n' ) {
if ( process() ) {
Serial.println( "Error" );
}
resetAll();
return;
}
// something received, but not \n. add to buffer
buffer[ len++ ] = c;
buffer[ len ] = '\0';
}
// -------------------------------------------------------------
// MYSTRTOK: equivalent to C strtok function that doesn't seem
// supported by arduino. Given a pointer to a string
// p, returns a pointer q past p that points to a char
// that is not a space. If cannot find one, return
// NULL.
// -------------------------------------------------------------
char* mystrtok( char* p, int skipNonBlank ) {
char* q=p;
if ( skipNonBlank ) {
for ( ; *q != ' ' && *q != '\0'; q++ );
if ( *q=='\0' ) return NULL;
}
for ( ; *q != '\0' && *q==' '; q++ );
if ( *q == '\0' ) return NULL;
if ( *q == ' ' ) return NULL;
return q;
}
// -------------------------------------------------------------
// PROCESS: if we're here it's because we have received a message
// from the UBUNTU PC.
// -------------------------------------------------------------
int process() {
char *p;
int len = strlen( buffer );
int intPin;
int intState;
//Serial.print( "buffer = " );
//Serial.print( buffer );
//--- if message less than 3 chars long, return ---
if ( len < 3 ) {
resetAll();
return 1; //error
}
//--- get the operation: 'w' or 'r'. Do some error checking---
operation = mystrtok( buffer, 0 );
if ( ( !operation || (*operation!='r' && *operation!='w') )
|| ( ( *operation=='r' && len < 3 ) ||( *operation=='w' && len < 7 ) ) ) {
resetAll();
return 1; // error
}
//--- get the mode: 'd' or 'a' and do some error checking ---
mode = mystrtok( operation + 1, 0 );
if ( !mode || ( *mode!='a' && *mode!='d' ) ) {
resetAll();
return 1; // success
}
//--- if operation is 'r' read the pins ---
if ( *operation == 'r' ) {
readPins( *mode );
resetAll();
return 0; // success
}
//--- if not, operation is 'w', then get pin # and state ---
pin = mystrtok( mode + 1, 0 );
if ( !pin ) {
resetAll();
return 1; // error
}
intPin = atoi( pin );
if ( intPin < 2 || intPin > 13 ) {
resetAll();
return 1; // error
}
//--- get the state of the output pin ---
state = mystrtok( pin+1, 1 );
if ( !state ) {
resetAll();
return 1; // error
}
intState = atoi( state );
if ( intState < 0 || intState > 1 ) {
resetAll();
return 1; // error
}
//--- write the state to the pin in question ---
writePin( *mode, intPin, intState );
resetAll();
return 0;
}
// -------------------------------------------------------------
// WRITEPIN: depending on mode, writes the state to the pin
// -------------------------------------------------------------
int writePin( char mode, int intPin, int intState ) {
if ( mode=='d' )
digitalWrite( intPin, intState );
if ( mode=='a' )
analogWrite( intPin, intState );
//delay( 50 ); // 0.05 sec
//Serial.println( "OK" );
return 0;
}
// -------------------------------------------------------------
// READPINS: read the status of all the pins and returns it as
// a string.
// -------------------------------------------------------------
int readPins( char mode ) {
int i;
if ( mode=='d' ) {
Serial.print( "d " );
for ( i=2; i<14; i++ ) {
Serial.print( digitalRead( i ) );
Serial.print( ' ' );
}
}
if ( mode=='a' ) {
Serial.print( "a " );
for ( i=0; i<6; i++ ) {
Serial.print( analogRead( i ) );
Serial.print( ' ' );
}
}
Serial.println();
return 0;
}