So for my project I have one Arduino Mega hooked up with a quadrature rotary encoder which is connected to the computer. An Arduino Uno is connected to a circuit I built, which in turn is connected to a valve and a touch connector (also connected to the computer via USB). Both of them should be controlled with a Python script.
If the rotary encoder is moved, I can read out a value via the serial port. The value of the rotary encoder is used in Python to move a dot on the screen. If the dot on the screen reaches a certain point, I want to give a signal to the valve to open (something like pin.write(1)
to turn on or pin.write(0)
to turn it off). At the same time I want to be able to detect the touch sensor if the circuit is closed.
The issue is now that I need to somehow need to read the rotary encoder, process the data and send it to the valve, as well as reading the touch sensor simultaneously. So far I have not found a way how to achieve this as my code does not function.
At the moment I have custom code on My Arduino Mega and a StandardFirmata
on the Arduino Uno, but I am open to other suggestions that could work.
Arduino Mega code:
/*
by Ben-Tommy Eriksen
https://github.com/BenTommyE/BenRotaryEncoder
*/
// Encoder connect to digital pin 2 and 3 on the Arduino.
int counter = 0;
//This variable will increase or decrease depending on the rotation of encoder
void setup() {
Serial.begin (4600);
//Setting up interrupt
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
}
void loop() {
// Send the value of counter
Serial.println (counter);
}
void ai0() {
// ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(3)==LOW) {
counter++;
} else {
counter--;
}
}
void ai1() {
// ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(2)==LOW) {
counter--;
} else {
counter++;
}
}
Python code:
import pyfirmata
import serial
import time
#Associate pyfirmata with python for my UNO board
port='COM5'
board= pyfirmata.Arduino(port)
#Use iterator thread to avoid buffer overflow
it = pyfirmata.util.Iterator(board)
it.start()
#Define pins (giving roles to pins: i.e. d=digital,7=pin number,i=input)
lickPin = board.get_pin('d:10:i') #records signal from the touch sensor
outPin1 = 12 #passes the signal to the valve
s = serial.Serial('COM4',4600)
while time<60s #generalized:
rotary = s.readline() #reads the counter of the rotary encoder form arduino
#convert the rotary to an integer try/except is needed to work
try:
var = long(rotary)
last_var = var
except:
var = last_var
pass
value1 = lickpin.read()
# Here I move the cursor up and down depending on the rotation of the encoder
# if the cursor moves above a certain value
if y>-18:
board.digital[12].write(1) #should open the valve
Unfortunately the code above does not trigger the valve to be opened, and I do not know why. Help is greatly appreciated. Thanks!
print()
s. Verify that you're even receiving the right value through the serial port.