Hello,
I am new to the arduino and arduino programming. I have been learning for the past week in order to try and build an open source solution for public libraries that will allow patrons to scan a barcode, validate using a network server, and accept coins to add a balance to the account for printing or fines.
I have an Arduino UNO and I have first learned that two interrupts was a problem. The barcode scanner uses two jues for clock and data.
Luckily, I was able to get around this using transistors to switch power on and off to scanner and coin accpetor to collect data on the same pin at different stages within the program.
The problem I face, since i am new to programming with Arduino, is the coin acceptor code uses attachInterrupt and the barcode scanner code uses pinMode(2, INPUT).
I have separated the code using boolean to determine if a valid barcode was scanned. If so, a signal is changed to LOW to kill power to the scanner, and another signal set to HIGH to power up the coin acceptor. But no matter what I do, I cannot seem to get accurate data from the coin acceptor to detect the pulses correctly in this code. I was able to get it working alone, but combined with scanner I do not have much luck.
I have attached my code so far. Any suggestions are appreciated. Thanks you.
Honestly, I dont know what "jues" are either! That must have been a typo. Sorry about that. What i meant was that the barcode scanner users two interrupts (pins 2,3 and 3 on the arduino).
The barcode scanner is a PS2/Metrologic scanner. I soldered a circuit to allow it to connect to the arduino power. ground, data (2), clock (3).
The coin acceptor is a programmable 3 pin (power, ground, signal) the signal cable is shares pin 2 with the scanner. The coind acceptor is 12 volt so i using a relay to enable and disable it. Here is the process:
Arduino boots up
A0 is set to LOW to ensure relay for coin acceptor relay is off
A1 is set to HIGH to ensure scanner is on via transistor
LCD displays "Scan card"
Once a card is scanned, an http request is made with the barcode as a query string
The server validates the barcode responding #1 for valid or #0 for invalid
If #1 is detected, A1 is set to LOW to power off the scanner to prevent duplicate scans
Also, A0 is set to HIGH to power on the coin acceptor relay
boolean scanOn is set to false, the main loop not attachesInterrupt and waits for pulses from the coin acceptor
the pulses are then counted:
25 pulses = quarter
10 pulses = dime
5 pulses = nickel
The coin acceptor works in standalone tests, but as soon as I try duplicate the functions in this code, it no longer works and I am stumped.
I don't know too much about this but would it not be sufficient to use one normal pin and an interrupt pin for the scanner? After a quick look at the PS2 protocol, it looks like you need to read data when a clock goes low.
No idea how coin acceptors work; counting pulses? But with above you will have an interrupt free. And, by the way, you can always use the pinchange interrupt on any other pin.
I probably don't understand your problem with the interrupts..
Ah, I see in your last reply that it indeed counts pulses.
I was not aware of a pinchange interrupt. Would this be the method used to detect the change if i move the clock pin to a different location?
This could possibly be a solution as I suspect running two devices on one pin, even if one is powered off, may be the cause of the misinterpretation of the signal.
Why don't you just use the two external interrupts provided?
External Interrupts: 2 and 3.
These pins can be configured to trigger an interrupt on a low value, a rising or falling edge,
or a change in value. See the attachInterrupt() function for details.
int ledPin = 13; // LED connected to digital pin 13
int inPin = 7; // pushbutton connected to digital pin 7
int val = 0; // variable to store the read value
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output
pinMode(inPin, INPUT); // sets the digital pin 7 as input
}
void loop()
{
val = digitalRead(inPin); // read the input pin
digitalWrite(ledPin, val); // sets the LED to the button's value
}
Whandall:
You do strange things to process two interrupt sources with one pin,
but you have two pins with that functionality on an UNO/Nano/Mini, 2 and 3.
Pinchange interrupts will work likewise, but are a little bit more complex to use,
because they are not natively supported by the Arduino core.
I need to "listen" to 3 pins, I am using both interrupts currently.
PS2 clock
PS2 data
Coin signal
What else do you propose? I am up to learning something since this is my first week!
PS2 Data does not need an interrupt, it will be read via the PS2 clock interrupt.
With that library only the clock pin needs to be an interrupt pin, the data pin does not, it can be most any IO pin but avoid using pins 0, 1, and 13. If your sketch uses SPI (for like SD card) or I2C or PWM or analog reads you have freedom to set the Data Line to an unused pin.
Whandall:
PS2 Data does not need an interrupt, it will be read via the PS2 clock interrupt.
I dont understand, this is how i am currently getting the data:
int clockPin = 3;
int dataPin = 2;
void setup(){
pinMode(dataPin, INPUT); // SCANNER PIN MODE
}
void loop(){
if(dataRead()){
if (dataValue == SCAN_BREAK) {
breakActive = 1;
}
for (int i = 0; i < quantityCodes; i++) {
byte temp = scanCodes[i];
if(temp == dataValue){
if(!breakActive == 1){
buffer[bufferPos] = characters[i];
bufferPos++;
}
}
}
}
int dataRead() {
byte val = 0;
// Skip start state and start bit
while (digitalRead(clockPin)); // Wait for LOW.
// clock is high when idle
while (!digitalRead(clockPin)); // Wait for HIGH.
while (digitalRead(clockPin)); // Wait for LOW.
for (int offset = 0; offset < 8; offset++) {
while (digitalRead(clockPin)); // Wait for LOW
val |= digitalRead(dataPin) << offset; // Add to byte
while (!digitalRead(clockPin)); // Wait for HIGH
}
// Skipping parity and stop bits down here.
while (digitalRead(clockPin)); // Wait for LOW.
while (!digitalRead(clockPin)); // Wait for HIGH.
while (digitalRead(clockPin)); // Wait for LOW.
while (!digitalRead(clockPin)); // Wait for HIGH.
return val;
}
I just tested with dataPin disconnected and I am unable to read data. My understanding is that the data pin tells the the Arduino when to listen to the clockPin so they must be connected to separate interrupts. Is this just the way I am doing it? Is their a better way?
You're not even using an interrupt. Yes, both pins must be connected to be able to read but only clock needs to be connected to an interrupt pin if you want to use interrupts.
p3rlphr33k:
I just tested with dataPin disconnected and I am unable to read data.
I switched off my computer and the monitor went blank. Same effect.
p3rlphr33k:
My understanding is that the data pin tells the the Arduino when to listen to the clockPin so they must be connected to separate interrupts.
From false assumptions you may imply anything but interrupts is wrong anyway.
The reading of data is directly controlled by the clock,
even if it were the other way around, there would only be one interrupt.
p3rlphr33k:
Is this just the way I am doing it?
Who knows if not you?
p3rlphr33k:
Is their a better way?
Yes, there is a better way.
Use one interrupt for the clock line and any other free pin for the data.
Carry out some investigation.
Google "Arduino ps/2 keyboard" and look what other people did.
Find the documentation of the PS/2 serial interface and study it.