Hi guys…as I progress with our interactive experience, I keep running into problems and questions pretty much every single day, this time with arduino…
instalation
Thank you,
António
Hi guys…as I progress with our interactive experience, I keep running into problems and questions pretty much every single day, this time with arduino…
instalation
Thank you,
António
easy way to do so is by using polling.
your reading software would then open the serial port.
like
ser = serial.Serial(’/dev/ttyUSB0’, 9600, timeout=0.1)
with the correct serial device, on windows you may simply use numbers.
now that you should be able to read and write chars on the serial device you can communicate in what ever way you want.
i usualy send a a start-byte (simply a char) to the controller, the controller reads it, checks the button states, and then answers with one or more chars containing the actual button states.
on the pc end it looks like:
data=[]
ser.flush()
ser.flushInput() #clears all buffers so no garbage is read or send
ser.write(chr(0xff)) #sends start-byto
for i in range(0,7): #for 7 byte long response
inchar = ser.read() #reads response
self.data.append(ord(inchar)) #and saves it as number
on the microcontroller end you would have something like:
while(1){
if(serial.read()==0xff){
serial.send(buttonStatus)
}
}
polling works a lot better with microcontrollers than events, especially if your reply is more than one byte long.
you may also want to keep the data transmitted over the comport low. 9600baud gives you about 1ms per byte of data. using higher baudrates and short responses is advised. also sending the new-data request right after finish reading on the pc is a good practice. altho you lack behind one frame with your input, the microcontroller wont block the panda thread that way.
is this what you mean on the microcontroller part:
const int button1Pin = 2; // the number of the pushbutton pin
const int button2Pin = 3;
const int button3Pin = 4;
const int button4Pin = 5;
// variables will change:
int buttonState[4]= {0}; // variable for reading the pushbutton status
int prevButtonState[4] = {0};
void setup()
{
Serial.begin(9600);
// initialize the pushbutton pin as an input:
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
pinMode(button3Pin, INPUT);
pinMode(button4Pin, INPUT);
}
void loop()
{
buttonState[0] = digitalRead(button1Pin);
buttonState[1] = digitalRead(button2Pin);
buttonState[2] = digitalRead(button3Pin);
buttonState[3] = digitalRead(button4Pin);
for(int i=0;i<4;i++)
{
Serial.println(buttonState[i]);
delay(100);
}
}
it’s reading 0’s and 1’s, 0000 no button pressed, 1111 all four buttons
now, figure out the pc part
the microcontroller part is almost right.
you should add an if( Serial.read() ) before the for-loop. otherwise you will get a constant stream of 0 and 1 and you cant tell which number relates to which button.
other than that it is ok. you wont need the delay part in the final version tho, will only slow things down. so, at least my recommended logic goes like:
pc sends a char. microcontroller receives that and sends 4 chars back with the button info. microcontroller wont send any further data until a new char from the pc is received.
Thank you Thomas,
I changed the arduino code to:
const int button1Pin = 2; // the number of the pushbutton pin
const int button2Pin = 3;
const int button3Pin = 4;
const int button4Pin = 5;
// variables will change:
int buttonState[4]= {0}; // variable for reading the pushbutton status
int prevButtonState[4] = {0};
void setup()
{
Serial.begin(9600);
// initialize the pushbutton pin as an input:
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
pinMode(button3Pin, INPUT);
pinMode(button4Pin, INPUT);
}
void loop()
{
buttonState[0] = digitalRead(button1Pin);
buttonState[1] = digitalRead(button2Pin);
buttonState[2] = digitalRead(button3Pin);
buttonState[3] = digitalRead(button4Pin);
if( Serial.read() ){
for(int i=0;i<4;i++)
{
Serial.println(buttonState[i]);
//delay(100);
}
}
}
It seems to be reading 0’s and 1’s depending on the state of the button…in python side, i tried
#-*- coding:utf8 -*-
from serial import *
#import time
def main():
ser=Serial('COM3')
print ser
ser.baudrate = 9600
ser.open()
data=[]
ser.flush()
ser.flushInput() #clears all buffers so no garbage is read or send
ser.write(chr(0xff)) #sends start-byto
for i in range(0,7): #for 7 byte long response
inchar = ser.read() #reads response
self.data.append(ord(inchar)) #and saves it as number
if(data[0]=='0' and data[1]=='1'):
print "bla"
#data [button 0, 1, 2, 3]
else:
print "bla bla"
#went wrong
if __name__=='__main__':
main()
I know there’s something wrong with the self part but is that the logic?
you send 4 byte from the μc to the pc. but your pc coder reads 7 bytes. you should change that to 4 bytes in the for i in range() part.
you should also delete the self thing. it slipped in there from my code which was originialy part of a class
slight progress:
arduino code
const int button1Pin = 2; // the number of the pushbutton pin
const int button2Pin = 3;
const int button3Pin = 4;
const int button4Pin = 5;
const char pin1d=0x01;
const char pin2d=0x02;
const char pin3d=0x04;
const char pin4d=0x08;
// variables will change:
int buttonState[4]= {0}; // variable for reading the pushbutton status
int prevButtonState[4] = {0};
void setup()
{
Serial.begin(9600);
// initialize the pushbutton pin as an input:
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
pinMode(button3Pin, INPUT);
pinMode(button4Pin, INPUT);
}
void loop()
{
//if(Serial.available()>0){
// if(Serial.read()==0xFF){
char retValue=0;
retValue=digitalRead(button1Pin)==1?retValue|pin1d:retValue&~pin1d;
retValue=digitalRead(button2Pin)==1?retValue|pin2d:retValue&~pin2d;
retValue=digitalRead(button3Pin)==1?retValue|pin3d:retValue&~pin3d;
retValue=digitalRead(button4Pin)==1?retValue|pin4d:retValue&~pin4d;
Serial.print(retValue);
// }
//}
}
python
#-*- coding:utf8 -*-
from serial import *
#import time
def main():
ser=Serial('COM3',9600)
print ser
while 1:
#data=[]
ser.flush()
ser.flushInput() #clears all buffers so no garbage is read or send
print ord(ser.read(size=1)) #sends start-byto
if __name__=='__main__':
main()
i can now read bytes of information from the buttons but there’s still a lot of trash going on…i wonder if it’s possible to read just the state…either x button is pressed or released