I am trying to create a print done sketch.
I an reading a logic high (5v) when idle and a logic 0 (0V) when its printing.
What I want to happen is when the print is finished, transition from low to high, the Arduino will beep.
The problem I am having is because its always high when idle, then low during printing, then high again (idle).
I can get it to beep on the high or the low but will be continuous beeps.
I would like just one set of beeps when the print is done, then it should wait for the high to low of a print...etc.
Here is what I have so far....it doesn’t work.
Any help would be appreciated!
Thanks!
#define Buzzer_PIN 2 // the number of the Buzzer pin
#define inputPin 3 // the number of the Input pin
const int LED1 = 5; // the number of the LED pin
int printStart = 0;
int printIdle = 0;
const int buzzerOn1 = 1; //Buzzer on/off
const int buzzerTime1 = 150; //Buzzer on time milliseconds
const int buzzerTime2 = 800; //Buzzer on time milliseconds
void setup() {
pinMode(inputPin, INPUT);
pinMode(LED1, OUTPUT);
pinMode(Buzzer_PIN, OUTPUT);
digitalWrite(Buzzer_PIN, LOW);
}
void loop() {
digitalWrite(Buzzer_PIN, HIGH);
if (digitalRead(inputPin) == HIGH) {
printIdle = 1; //High
printStart = 0; //Low
}
else if (digitalRead(inputPin) == LOW) {
printIdle = 0; //Low
printStart = 1; //High
}
if ( printIdle == 0 && printStart == 1) {
buzzer();
delay(5000);
}
}
void buzzer() { //Buzzer control
if (buzzerOn1 == 1) {
digitalWrite(Buzzer_PIN, HIGH); //Buzzer 1
digitalWrite(LED1, HIGH); // turn the LED on (HIGH is the voltage level)
delay(buzzerTime1);
digitalWrite(Buzzer_PIN, LOW); //Buzzer 1
digitalWrite(LED1, LOW); // turn the LED off by making the voltage LOW
delay(buzzerTime2);
digitalWrite(Buzzer_PIN, HIGH); //Buzzer 1
digitalWrite(LED1, HIGH); // turn the LED on (HIGH is the voltage level)
delay(buzzerTime1);
digitalWrite(Buzzer_PIN, LOW); //Buzzer 1
digitalWrite(LED1, LOW); // turn the LED off by making the voltage LOW
delay(buzzerTime2);
digitalWrite(Buzzer_PIN, HIGH); //Buzzer 1
digitalWrite(LED1, HIGH); // turn the LED on (HIGH is the voltage level)
delay(buzzerTime1);
digitalWrite(Buzzer_PIN, LOW); //Buzzer 1
digitalWrite(LED1, LOW); // turn the LED off by making the voltage LOW
digitalWrite(Buzzer_PIN, HIGH);
delay(buzzerTime2);
}
}
File -> Examples -> 02. Digital -> BlinkWithoutDelay
This will teach you how to not use delay. Delay stops your sketch from running and wastes processor cycles.
Then you need to rewrite your code in way that the loop gets executed as often as possible. Instead of thinking about completing a task think about what needs to be done in that moment and then move on. Do not stop in your code. Your Arduino is no human and does not need vacation. As jimLee said use enums and state variables to keep track.
A few things that might help
Try to separate your buzzer and your LED code. The function is named buzzer. You might want to use the LED for something else later.
Use a naming scheme. e.g. constants all CAPITAL_WITH_UNDERSCORE
#define BUZZER_PIN 2 #define INPUT_PIN 3 // Better describe what the input is e.g. PRINTER_ACTIVE_PIN #define LED_PIN 5 // same here
If you need a global variable only in one function use static and declare the variable inside the function. That way you can copy the code to some other project later, you can re-use the name in other functions and your code will be easier to read. e.g.
void buzzer(){
static int state = 0; // set to zero only the first time the function runs
...
}
Just a quick update.
I moved away from the state change because the particular line I am monitoring has an issue.
It picking up some pulses, probably capacitively coupled from a solenoid. Cant change the board unfortunately.
They are just long enough, about 5uS for the Arduino to pick it up and trigger.
I found the pulseInLong() worked so much better. I was able to adjust the timing so that it will only see a pulse of 90mS or longer.
That’s perfect for the sensor I am monitoring and completely ignores the pulse that coupled in from the solenoid.
As far as code logic is concerned, this is how you would trigger a buzzer when a state switches from low to high. It will run the method one time until another low to high happens:
Do you have pullup or pulldown resistors on input pins to keep the pins from "floating" and causing false HIGHs or LOWs when the button is not pressed?
aarg:
Is there a freewheeling diode in parallel with the solenoid coil?
Unfortunately that assembly isn't easily accessible without completely dissembling the machine and I don't have the fixturing to put it back together.
It looks more like coupling on the scope. The traces on the board I think are running near each other, as are the connecting wires.
I am tapping off a test point from an LM339 comparator which has a pullup already installed.
Using the pulseInLong() I was able to get everything working as intended.