231a-af Lab 6 Report
Contents
Lab 6 Report
This lab is designed to teach us how to interface the Arduino with the PC. We are going to make the Arduino keep on listening to commands it gets from the assembly language on the PC, and execute each command as it receives them.
Getting the SimpleMessageSystem Library for the Arduino
- Download and unzip the library file from the Arduino Playground
sudo su
cd
cd arduino-0010/hardware/libraries
wget http://www.arduino.cc/playground/uploads/Code/SimpleMessageSystem.zip
unzip SimpleMessageSystem.zip
rm SimpleMessageSystem.zip
chown -R 1000:1000 SimpleMessageSystem
- Open up the Arduino GUI and create this new sketch (save it in the /root/sketches folder as loop).
/*
---- SimpleMessageSystem Example 1 ----
Control Arduino board functions with the following messages:
r a -> read analog pins
r d -> read digital pins
w d [pin] [value] -> write digital pin
w a [pin] [value] -> write analog pin
Base: Thomas Ouellet Fredericks
Additions: Alexandre Quessy
*/
// Include de SimpleMessageSystem library
// REMOVE THE FOLLOWING LINE IF USING WIRING
#include <SimpleMessageSystem.h>
void setup() {
// The following command initiates the serial port at 9600 baud. Please note this is VERY SLOW!!!!!!
// I suggest you use higher speeds in your own code. You can go up to 115200 with the USB version, that's 12x faster
Serial.begin(9600); //Baud set at 9600 for compatibility, CHANGE!
}
void loop() {
if (messageBuild() > 0) { // Checks to see if the message is complete and erases any previous messages
switch (messageGetChar()) { // Gets the first word as a character
case 'r': // Read pins (analog or digital)
readpins(); // Call the readpins function
break; // Break from the switch
case 'w': // Write pin
writepin(); // Call the writepin function
}
}
}
void readpins(){ // Read pins (analog or digital)
switch (messageGetChar()) { // Gets the next word as a character
case 'd': // READ digital pins
messageSendChar('d'); // Echo what is being read
for (char i=2;i<14;i++) {
messageSendInt(digitalRead(i)); // Read pins 2 to 13
}
messageEnd(); // Terminate the message being sent
break; // Break from the switch
case 'a': // READ analog pins
messageSendChar('a'); // Echo what is being read
for (char i=0;i<6;i++) {
messageSendInt(analogRead(i)); // Read pins 0 to 5
}
messageEnd(); // Terminate the message being sent
}
}
void writepin() { // Write pin
int pin;
int state;
switch (messageGetChar()) { // Gets the next word as a character
case 'a' : // WRITE an analog pin
pin = messageGetInt(); // Gets the next word as an integer
state = messageGetInt(); // Gets the next word as an integer
pinMode(pin, OUTPUT); //Sets the state of the pin to an output
analogWrite(pin, state); //Sets the PWM of the pin
break; // Break from the switch
case 'd' : // WRITE a digital pin
pin = messageGetInt(); // Gets the next word as an integer
state = messageGetInt(); // Gets the next word as an integer
pinMode(pin,OUTPUT); //Sets the state of the pin to an output
digitalWrite(pin,state); //Sets the state of the pin HIGH (1) or LOW (0)
}
}
Assembly Part on the PC
Outputting Information
LED On
- Create a program called ledOn that turns on the LED connected to Pin 13
- Assemble/compile the files
nasm -f elf -F stabs asm_io.asm nasm -f elf -F stabs ledOn.asm gcc -o ledOn driver.c ledOn.o asm_io.o
- Run the program
./ledOn
The LED turns on!
LED Off
- Make a copy of ledOn.asm under the name ledOff.asm, modify it, and compile it. Use it to turn OFF the LED.
;;; -------------------------------------------------------------------
;;; ledOff.asm
;;; Faith Unterseher and Jessica Lin
;;; This program turns the LED Off on the Arduino stamp.
;;; The program simply writes an \r -terminated string to /dev/ttyUSB0
;;; that simply puts a 0 on Digital Pin 13. The string is "w d 13 0\r"
;;;
;;;
;;; nasm -f elf ledOff.asm
;;; nasm -f elf asm_io.asm
;;; gcc -m32 -o ledOff driver.c asm_io.o ledOff.o
;;; (use -m32 on 64-bit machines)
;;;
;;; Without the asm_io.* and driver.c wrappers, then link with
;;; ld -melf_i386 ledOff.o -o ledOff
;;; (use -melf_i386 on 64-bit machines)
;;;
;;; To Execute:
;;;
;;; ./ledOff
;;;
;;; -------------------------------------------------------------------
%include "asm_io.inc"
%assign EXIT 1
%assign OPEN 5
%assign CLOSE 6
%assign READ 3
%assign CREATE 8
%assign WRITE 4
%assign STDOUT 1
%assign O_CREAT 64
%assign O_RDONLY 0
%assign O_WRONLY 1
%assign O_APPEND 1024
%assign O_RDWR 2
%assign S_IRUSR 00400q
%assign S_IWUSR 00200q
%assign S_IXUSR 00100q
;;; ____ _
;;; | _ \ __ _| |_ __ _
;;; | | | |/ _` | __/ _` |
;;; | |_| | (_| | || (_| |
;;; |____/ \__,_|\__\__,_|
;;;
section .data
errorMsg db "Error accessing file!",0x0a, 0
errorMsg1 db "Error opening file!",0x0a, 0
usb db "/dev/ttyUSB0",0
handle dd 0
noRead dd 0
msg db "w d 13 0", 0x0d
msgLen equ $-msg
section .bss
%assign MAXBUF 100
buffer resb MAXBUF
;;; ____ _
;;; / ___|___ __| | ___
;;; | | / _ \ / _` |/ _ \
;;; | |__| (_) | (_| | __/
;;; \____\___/ \__,_|\___|
;;;
section .text
global asm_main
asm_main:
;;; open file, write string, close file...
mov ebx, usb
call openFile
mov dword[handle], eax
mov ebx, [handle]
mov ecx, msg
mov edx, msgLen
call writeFile
mov ebx, dword[handle]
call closeFile
;;; we're done!
ret
;;; if there's a problem, we exit right away
exit:
mov eax,EXIT
mov ebx,0
int 0x80 ; final system call
;;; --------------------------------------------------------
;;; openFile
;;; put address of ASCIIZ file name in ebx
;;; handle returned in eax
;;; --------------------------------------------------------
openFile:
mov eax, OPEN
mov ecx,O_WRONLY | O_APPEND ; mode for opening file
mov edx,S_IRUSR | S_IWUSR
int 0x80
test eax,eax ; test for errors
jns doneOpenFile
mov eax, errorMsg1
call print_string
jmp exit
doneOpenFile:
ret ; handle in eax
;;; --------------------------------------------------------
;;; closeFile: the handle must be in ebx on entry.
;;; Closes the file
;;; --------------------------------------------------------
closeFile:
mov eax,CLOSE
int 0x80
ret
;;; --------------------------------------------------------
;;; readFile: on entry:
;;; handle in ebx
;;; buffer address in ecx
;;; max buffer length in edx
;;; on exit: number of chars read in eax
;;; --------------------------------------------------------
readFile:
mov eax,READ
int 0x80
test eax,eax
jns doneReadFile
mov eax, errorMsg
call print_string
jmp exit
doneReadFile:
ret
;;; --------------------------------------------------------
;;; writeFile:
;;; on entry:
;;; handle is in ebx
;;; buffer address is in ecx,
;;; number of chars is in edx.
;;; --------------------------------------------------------
writeFile:
mov eax,WRITE
int 0x80
test eax,eax
jns doneWriteFile
mov eax, errorMsg
call print_string
jmp exit
doneWriteFile:
ret
- Remember to check the Arduino Reference Page to debug your sketch...
LED On/Off
- Now make your assembly program send an ON message, followed by an OFF message in an endless loop
;;; -------------------------------------------------------------------
;;; ledOnOff.asm
;;; Faith Unterseher and Jessica Lin
;;; This program turns the LED On and Off continuously on the Arduino stamp.
;;; The program simply writes \r -terminated strings to /dev/ttyUSB0
;;; that simply put a 0 or 1 on Digital Pin 13. The strings are "w d 13 0\r"
;;; and "w d 13 1\r".
;;;
;;;
;;; nasm -f elf ledOnOff.asm
;;; nasm -f elf asm_io.asm
;;; gcc -m32 -o ledOnOff driver.c asm_io.o ledOnOff.o
;;; (use -m32 on 64-bit machines)
;;;
;;; Without the asm_io.* and driver.c wrappers, then link with
;;; ld -melf_i386 ledOnOff.o -o ledOnOff
;;; (use -melf_i386 on 64-bit machines)
;;;
;;; To Execute:
;;;
;;; ./ledOnOff
;;;
;;; -------------------------------------------------------------------
%include "asm_io.inc"
%assign EXIT 1
%assign OPEN 5
%assign CLOSE 6
%assign READ 3
%assign CREATE 8
%assign WRITE 4
%assign STDOUT 1
%assign O_CREAT 64
%assign O_RDONLY 0
%assign O_WRONLY 1
%assign O_APPEND 1024
%assign O_RDWR 2
%assign S_IRUSR 00400q
%assign S_IWUSR 00200q
%assign S_IXUSR 00100q
;;; ____ _
;;; | _ \ __ _| |_ __ _
;;; | | | |/ _` | __/ _` |
;;; | |_| | (_| | || (_| |
;;; |____/ \__,_|\__\__,_|
;;;
section .data
errorMsg db "Error accessing file!",0x0a, 0
errorMsg1 db "Error opening file!",0x0a, 0
usb db "/dev/ttyUSB0",0
handle dd 0
noRead dd 0
msg db "w d 13 0", 0x0d
msgLen equ $-msg
msg2 db "w d 13 1", 0x0d
msg2Len equ $-msg2
section .bss
%assign MAXBUF 100
buffer resb MAXBUF
;;; ____ _
;;; / ___|___ __| | ___
;;; | | / _ \ / _` |/ _ \
;;; | |__| (_) | (_| | __/
;;; \____\___/ \__,_|\___|
;;;
section .text
global asm_main
asm_main:
;;; open file, write string, close file...
onoff:
mov ebx, usb
call openFile
mov dword[handle], eax
mov ebx, [handle]
mov ecx, msg
mov edx, msgLen
call writeFile
mov ebx, dword[handle]
call closeFile
call delay
mov ebx, usb
call openFile
mov dword[handle], eax
mov ebx, [handle]
mov ecx, msg2
mov edx, msg2Len
call writeFile
mov ebx, dword[handle]
call closeFile
call delay
jmp onoff
;;; we're done!
ret
delay:
mov ecx, 10000000
delayloop:
loop delayloop
ret
;;; if there's a problem, we exit right away
exit:
mov eax,EXIT
mov ebx,0
int 0x80 ; final system call
;;; --------------------------------------------------------
;;; openFile
;;; put address of ASCIIZ file name in ebx
;;; handle returned in eax
;;; --------------------------------------------------------
openFile:
mov eax, OPEN
mov ecx,O_WRONLY | O_APPEND ; mode for opening file
mov edx,S_IRUSR | S_IWUSR
int 0x80
test eax,eax ; test for errors
jns doneOpenFile
mov eax, errorMsg1
call print_string
jmp exit
doneOpenFile:
ret ; handle in eax
;;; --------------------------------------------------------
;;; closeFile: the handle must be in ebx on entry.
;;; Closes the file
;;; --------------------------------------------------------
closeFile:
mov eax,CLOSE
int 0x80
ret
;;; --------------------------------------------------------
;;; readFile: on entry:
;;; handle in ebx
;;; buffer address in ecx
;;; max buffer length in edx
;;; on exit: number of chars read in eax
;;; --------------------------------------------------------
readFile:
mov eax,READ
int 0x80
test eax,eax
jns doneReadFile
mov eax, errorMsg
call print_string
jmp exit
doneReadFile:
ret
;;; --------------------------------------------------------
;;; writeFile:
;;; on entry:
;;; handle is in ebx
;;; buffer address is in ecx,
;;; number of chars is in edx.
;;; --------------------------------------------------------
writeFile:
mov eax,WRITE
int 0x80
test eax,eax
jns doneWriteFile
mov eax, errorMsg
call print_string
jmp exit
doneWriteFile:
ret
- Measure the frequency of the LED turning ON and OFF
- The LED turns ON/OFF at .01Hz
- How could we make the LED blink faster, but still be able to control this blinking from the assembly program?
- We can make the LED blink faster through the assembly program by decreasing the delay inbetween the two states of ON/OFF.