I would like to turn on and off the output of two pins on my arduino independently from each other. However, so far all my attempts have failed.
My current idea is to save the status (which I chose to be 0 as 'low' and 'high' as 1) of each of the pins in an integer array and then change the status of the pin depending of the entry in the variable. However, the entries in the variable are always set back to 0 and I do not know why this is happening.
This is my arduino code
const byte numChars = 32;
byte receivedChars[numChars];
boolean newData = false;
const int num_of_pins=2;
int output_pins[num_of_pins]={22,26};
int status_pins[num_of_pins]={0,0};
void setup() {
int ii=0;
Serial.begin(9600);
for(ii=0; ii<num_of_pins; ii++){
pinMode(output_pins[ii],OUTPUT);
}
}
void loop() {
recvWithStartEndMarkers();
chooseFunction();
}
void chooseFunction(){
if (receivedChars[0]==0){
shutter();
}
}
void shutter(){
// get number of pin
int pin_number_rcvd;
int ii;
int pin_status_rcvd;
pin_number_rcvd=receivedChars[1];
pin_status_rcvd=receivedChars[2];
//check all status of pins and turn on and off
for (ii=0; ii<num_of_pins; ii++){
if (pin_number_rcvd==output_pins[ii]){
status_pins[ii]=pin_status_rcvd;
}
if (status_pins[ii]==0){
digitalWrite(output_pins[ii],LOW);
}
if (status_pins[ii]==1){
digitalWrite(output_pins[ii],HIGH);
}
}
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
byte startMarker = 8;
byte endMarker = 9;
byte rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '0円'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
I use pyserial to send the input data to the arduino. my python code:
import serial
import time, struct, sys
ser=serial.Serial('COM17', 9600, timeout=10)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
pin_number= int(sys.argv[1])
high_or_low=int(sys.argv[2])
ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))
I am using an ArduinoDue together with the arduino IDE.
1 Answer 1
Your problem is in one tricky option for arduino's com connection. When you reopen COM port where arduino is connected your arduino resets automatically.
Here's workaround from arduino.cc:
DisablingAutoResetOnSerialConnection
The simple way that doesn't require any permanent modifying of your hardware or software configuration changes:
Stick a 120 ohm resistor in the headers between 5v and reset (you can find these on the isp connector too). 120 is hard to find so just combine resistors. Don't go below 110 ohms or above 124 ohms, and don't do this with an isp programmer attached. You can just pull out the resistor when you want auto-reset back.
http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
Or you can just modify you script to be able to start over without reopening it. For example use a loop there and some exit command to end that loop:
try:
while True:
do_something()
except KeyboardInterrupt:
pass
https://stackoverflow.com/questions/13180941/how-to-kill-a-while-loop-with-a-keystroke
Replace do_something()
with this part of your code:
ser.reset_input_buffer()
ser.reset_output_buffer()
pin_number= int(sys.argv[1])
high_or_low=int(sys.argv[2])
ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))
I hope I was clear enough.
receivedChars[0]==0
butser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))
is sent (eg it's 1, not 0)I would like to turn on and off the output of two pins on my arduino independently from each other.