I’m trying to program an Arduino to control ultrasonic sensor which functions as a base to driver a 2 channel solid state relais (low lvl trigger), piezo buzzer and a ballast. The ballast will be dimmed over a 1-10v port through PWM pin 9 (NPN transistor, capacitor, and some resistors).
The problem I’m facing is that I don’t exactly know how to program the Arduino in such a way it can cycle trough 4 different behaviors sets, accordingly to the distance that a person is away from the sensor. (Excuse my poor English) Let me clarify:
Maximum range: 224 centimeter
If is < distance between 223-170 centimeter> then
tone khz 1000
Pwm value 1 —> 30
SSR CH1 ON, 0,5 seconds OFF)
SSR CH2 ON, 0,5 seconds OFF)
If is < distance between 170-110 centimeter> then
tone khz 1000 —> 700
Pwm value 30 —> 110
If is < distance between 110-50 centimeter> then
tone khz 700 —> 500
Pwm value 110 —> 170
If is < distance between 50-1 centimeter> then
tone khz 500 —> 200
Pwm value 170 —> 224
PWM (flickering)
SSR CH1 ON, 3 seconds, OFF)
SSR CH2 ON, 3 seconds, OFF)
How would I program these different behavior sets? By using the case argument or will if/else statements also work? I’ve seen that I can use the map() argument to drive ranges, will I need that argument to map the range of the tones of the buzzer?
Sorry for all these questions, I hope you guys can help me out.
Greets from the netherlands!
#include <elapsedMillis.h>
elapsedMillis timeElapsed;
unsigned int interval = 6000; // one second in ms
#define trigPin 10
#define echoPin 12
#// define ledPin 13 //origineel, niet nodig
int led = 3; // PWM naar 1-10v
int brightness = 1; //hoe hoog de output is
int fadeAmount = 1; // schroef met 1 stap omhoog
const int buzzer = 5; // buzzer op arduino pin 9
int in1 = 8;
int in2 = 7;
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT); // 1-10v wordt aangestuurd door pwm waarde
pinMode(buzzer, OUTPUT); // buzzer op pin 5 is output
pinMode(in1, OUTPUT); // 2ch SSR high (low lvl trigger)
digitalWrite(in1, HIGH); //ch1 off
pinMode(in2, OUTPUT);
digitalWrite(in2, HIGH); //ch2 off
}
void loop() {
// -- 1-10v dim
analogWrite(led, brightness); // stel brightness in op pwm output
brightness = brightness + fadeAmount;
if (brightness <= 0 || brightness >= 255){
fadeAmount = - fadeAmount;
}
delay(30);
// -- 1-10v dim
long duration, distance; //--- ultrasonic
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
// delayMicroseconds(1000); - Removed this line
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1; // --- ultrasonic
if (distance >= 500 || distance <= 260){
//Serial.println("Out of range"); // heb ik niet nodig.
analogWrite (9,1); //pin 9, brightness 1
}
else {
Serial.print(distance); // gebruik dit om output te monitoren,
// kan bij final versie weg
Serial.println(" cm"); // same
Serial.println(brightness);
}
if (distance <= 223 && distance >= 170){ // execute stuff_01
analogWrite (9, 30);
tone(buzzer, 10000);
while(timeElapsed < interval){ //interval is 1 sec
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
}
// Serial.println(brightness); //check brightness line
}
else if (distance <= 170 && distance >= 110){ //execute different stuff
analogWrite(9, 110);
tone(buzzer, 20000);
}
else if (distance <= 110 && distance >= 50){
analogWrite(9, 110);
tone(buzzer, 30000);
}
else if (distance <= 50 && distance >= 1){
analogWrite(9, 110);
tone(buzzer, 40000);
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
while(timeElapsed < interval){ //interval is 1 sec
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
}
}
else{ // eindstatement ofwel buiten range,
// defined als
analogWrite(9,1); //terug naar zachtjes aan
noTone(buzzer); //uit?
}
delay(5);
}
This is something i worked on, am i understandig you correctly? I've inserted multiple if else and else if's for specifying different behaviour sets. It's important the sensor stays active during the cycles, so therefore i've tried to stay away from using big delays when it comes to dealing with the SSR i'm planning to use.
you're right, i've changed the ranges to not overlap each other. A thing that is not yet behaving correctly is the output to the pwn pin 3. I've used the standard example for fading an LED but what i actually want is to have the led go up to the value specified in the second action.
Sorry for not being clear. I'd like every behaviour set to play indefinitely. When a visitor is in the hit area of the ultrasonic sensor, it keeps maintaining one behaviour set and changes when the visitor comes closer or distances his or herself from the sensor, the a different behaviour set is triggered and also plays in definitely.
By incrementing i mean that the value counts up to the value specified, so:
Do you mean doing something like for (byte pwm=110; pwm<=170; pwm++) analogWrite(9,pwm);this of course would run very quickly and not for ever - but is that what you mean by incrementing?
Yes, that's what i mean! Great. Is it difficult to incorporate this for loop into my code, in conjunction with the specified ranges by the ultrasonic sensor?
The ultrasonic sensor functions as the heart of the installation and the other components react to the values it measures.
According to the ranges of the ultrasonic, it triggers:
PWM pin; (the values drive the intensity of a dimmable ballast) through a NPN transistor. The ballast delivers the voltage of 1-10v. Values between 1 and 224 are used to alter the intensity of a fluorescent tube.
piezo (different tones)
2channel 5v to 230AC SSR, low lvl trigger. Switches a 5v fan and 24v ultrasonic mist maker.
What i'm struggling with is the Arduino cycling through the different if/else and else if statements, i'm unable to walk through these different behaviour sets (ultrasonic rangefinder doesn't respond and the piezo does make 2 different sounds but the ballast doesn't play along.
That's a good tip, i'll bear that in mind to really dive in next time.
The only issue is that this code is due tomorrow for an art exhibition (i know i started way too late ), is it really that difficult to make this work? I'd hoped one of you experts could solve this in a flash.
I didn't mean to offend, i'm just looking for a nudge in the right direction (and feeling a little desperate to be honest) But thank you all for replying to this thread.
You need some sort of a state machine with the “doing multiple thing at the same time” approach using millis() you should read the post pinned at the top of the forum
The loop reads the distance from time to time, like x times per second (use the millis technic and no delay for this) and not block code for long
Based on the last read value decide what the PWM does. Same thing here - this should be based on its own timing using similar milli. remember previous animation stage and adapt to the cycle you want to see, do one step (increasing) at the right time