Arduino as gateopener - arduino

I am new to codeing arduino.
I have a project which is about useing an arduino as a gate opener, but only when the temperature gets above 24 degrees.
The problem is how do i get the arduino to send a signal to the relay to open, but only once?
I tried with if statements and trying under there to run with some while(1); but that seems to end the whole script. so that does not do what i want it to..
```
float temp;
int tempPin = A0;
int Relay1 = 13;
bool ronce = false;
void setup() {
Serial.begin(9600);
pinMode(Relay1,OUTPUT);
}
void loop() {
delay(500);
temp = analogRead(tempPin);
temp = temp * 0.48828125;
Serial.print(temp);
if(temp>24){
ronce == true;
Serial.println(" Temp over 24 degree");
if (ronce = true){
Serial.println(" Ronce is true.");
while(1){
Serial.println("runOnce");
digitalWrite(Relay1,HIGH);
delay(500);
digitalWrite(Relay1,LOW);
}
}
}
else {
ronce == false;
Serial.println(" failure");
}
}
I want it to send a signal at 24 degrees to the relay to go on NC & ground and then turn off after 500 ms ish.
then it should not turn on again until when it gets below 24 degrees again.
The output turns out between 20-37 degrees so the LM35 does as i want it to, it is just the code.

You just need to create a read function and then read it until it reaches above 24, then just turn on relay and wait again until the temp gets below 24.
int tempPin = A0;
int Relay1 = 13;
float read_temp()
{
float sum = 0;
float temp;
for (int i = 0; i < 500; i++)
{
sum += analogRead(tempPin);
delayMicroseconds(100);
}
temp = sum / 500;
temp = temp * 0.48828125;
return temp;
}
void setup()
{
Serial.begin(9600);
pinMode(Relay1, OUTPUT);
}
void loop()
{
if (read_temp() > 24)
{
Serial.println("Temp over 24 degree");
digitalWrite(Relay1, HIGH);
delay(500);
digitalWrite(Relay1, LOW);
// wait until temp reach below 23.5
while (read_temp() > 23.5)
;
}
}

Related

I am trying to merge 3 separate DataLogger codes in to one. they work fine individually; however I can get all 3 to work together

I am trying to merge 3 separate DataLogger codes in to one. they work fine individually; however I can get all 3 to work together, can anyone help?
#include <SPI.h>
#include <SD.h>
#include "RTClib.h"
RTC_DS1307 rtc;
int sensor = A0;
int sensorInput;
double temp;
int led = 13;
int sensorMotion = A1;
int state = LOW;
int val = 0;
const char* filename = "DataLogger.csv";
File file;
void setup() {
Serial.begin(9600);
#ifndef ESP8266
while (!Serial);
#endif
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
abort();
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
pinMode(10, OUTPUT);
if (!SD.begin(10)) {
Serial.println("Error : Push the reset button");
for (;;);
}
file = SD.open(filename, FILE_WRITE);
if (file.size() == 0) {
file.println("Brightness value per seconds");
file.flush();
}
}
DateTime time = rtc.now();
val = digitalRead(sensor); // read sensor value
if (val == HIGH) { // check if the sensor is HIGH
digitalWrite(led, HIGH); // turn LED ON
delay(500); // delay 100 milliseconds
if (state == LOW) {
Serial.println(String("Motion detected
")+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.println(String("Motion detected
")+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.flush();
state = HIGH; // update variable state to HIGH
}
}
else {
digitalWrite(led, LOW); // turn LED OFF
delay(500); // delay 200 milliseconds
if (state == HIGH){
Serial.println("Motion stopped!");
state = LOW; // update variable state to LOW
}
}
}
void loop() {
measure();
delay(1000);
DateTime time = rtc.now();
sensorInput = analogRead(A0);
temp = (double)sensorInput / 1024;
temp = temp * 5;
temp = temp - 0.5;
temp = temp * 100;
delay(1000);
Serial.println(String(temp)+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.println(String(temp)+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.flush();
}
void measure() {
DateTime time = rtc.now();
int lightvalue = analogRead(A0);
Serial.println(String(lightvalue)+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.println(String(lightvalue)+","+time.timestamp(DateTime::TIMESTAMP_TIME)+","+time.timestamp(DateTime::TIMESTAMP_DATE));
file.flush();
}

Implementing the function interrupt with if statements

I want to implement the function interrupt () but I don't know exactly how..In this case there is 2 for loops which can be seen in the code:I want whenever one of the 2 buttons is pressed the process inside the loop to be interrupted immediately:
void loop() {
int brightButton = digitalRead(K1);
int ldrStatus = analogRead(ldrPin);
if (brightButton == LOW && ldrStatus >= 200)
{
for (int i = 0; i < 10; i++)
{
digitalWrite(greenLed, HIGH);
tone(buzzer,400);
delay(500);
noTone(buzzer);
delay(500);
}
}
else {
digitalWrite(greenLed, LOW);
}
int tempButton = digitalRead(K2);
int valNTC = analogRead(NTC);
if (tempButton == LOW && valNTC > 512)
{
for (int i = 0; i <10; i++)
{
digitalWrite(redLed, HIGH);
tone(buzzer,450);
delay(300);
noTone(buzzer);
delay(1000);
}
}
else {
digitalWrite(redLed, LOW);
}
}
Example code from the Arduino manual:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
Note that this will interrupt the for loop and return to it once the interrupt service routine is finished.
If you want to abort the for loop check the pin state in every loop cycle and break if you want to leave the for loop or return if you want to leave loop().
Of course this is not "immediately".

Trying to make a password using an array with arduino

I am a beginner to using the arduino and I'm stuck at a certain problem. What I have is a programm that prints numbers to the console with the press of a button. What I'm trying to get is to the point that I enter 4 numbers after which it checks if it is the same as an array of numbers that I set before.
Now the problem is that I dont know how to make the programm check if the array I entered with the buttons is the same as the one I wrote before.
int b1 = 4;
int bs1 = 0;
int b2 = 2;
int bs2 = 0;
int b3 = 3;
int bs3 = 0;
int count = 0;
int correctcode[] = {2,3,3,1};
int code[4];
void setup() {
// put your setup code here, to run once:
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode (b1, INPUT);
pinMode (b2, INPUT);
pinMode (b3, INPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
bs1 = digitalRead(b1);
bs2 = digitalRead(b2);
bs3 = digitalRead(b3);
if (bs1 == HIGH) {
count++;
Serial.print ("1");
delay(500);
if (count == 4){
Serial.println ("pincode ingevoerd, checking....");
}
}
if (bs2 == HIGH) {
count++;
Serial.print ("2");
delay(500);
if (count == 4){
Serial.println ("pincode ingevoerd, checking....");
}
}
if (bs3 == HIGH) {
count++;
Serial.print ("3");
delay(500);
if (count == 4){
Serial.println ("pincode ingevoerd, checking....");
}
}
}
// Button pins ( with external pulldown resistors )
const byte b1 = 4;
const byte b2 = 2;
const byte b3 = 3;
// Signal pins
const byte greenPin = 12;
const byte redPin = 13;
byte count = 0; // 0 ... 4 counted button presses
byte correctcode[4] = {2,3,3,1};
byte code[4];
void setup() {
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode (b1, INPUT);
pinMode (b2, INPUT);
pinMode (b3, INPUT);
Serial.begin(9600);
}
void loop() {
bool bs1 = digitalRead(b1);
bool bs2 = digitalRead(b2);
bool bs3 = digitalRead(b3);
if (bs1) add(1);
else if (bs2) add(2);
else if (bs3) add(3);
}
void add( byte value ) {
Serial.print (value);
code[count++] = value;
if (count == 4) {
count=0;
if (check()) correct();
else wrong();
}
else
delay(500);
}
bool check() {
for (byte i=0; i < 4; i++) {
if (code[i] != correctcode[i]) {
return false;
}
}
return true;
}
void wrong() {
Serial.println(" -> wrong !");
digitalWrite(redPin, HIGH);
delay(1000);
digitalWrite(redPin, LOW);
}
void correct() {
Serial.println(" -> correct !");
digitalWrite(greenPin, HIGH);
delay(300);
digitalWrite(greenPin, LOW);
}
Compiled, but Untested
Don't duplicate code, but create functions. This can make code easier to read.
If you do not want an autorepeat ( after 500 ms ) for your buttons, better check for state changes (Pressed -> Released)
If multiple buttons are pressed, I added a priority. You might want to discard that state instead.
For more than 3 buttons, read about arrays :)

Problem with interruptions in Arduino Uno

I work with interruptions in Arduino UNO. In this project, I want to when the Door is opened the LED blink 10 times, and when the door is closed again, stop blinking the LED and exit the function. But in this code the LED only turn on and off once and it does not flash again.
My other problem is that, when the door is opened or closed, sometimes the opened or closed word appears several times in the Series monitor.
const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin
volatile int SensorState = LOW; // 0 close - 1 open wwitch
void setup()
{
Serial.begin(9600);
pinMode(LED_Red, OUTPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}
void DoAction()
{
SensorState = digitalRead(DOOR_SENSOR);
if (SensorState == HIGH) {
Serial.println("Opened");
blinkLED(10, 500);
}
else {
Serial.println("Closed");
}
}
void blinkLED(int repeats, int time)
{
for (int i = 0; i < repeats; i++) {
if (SensorState == HIGH) {
digitalWrite(LED_Red, HIGH);
delay(time);
digitalWrite(LED_Red, LOW);
delay(time);
}
else
return;
}
}
void loop()
{
}
You can't simply put a delay() on an interrupt's function. You need to just set a flag when the door is opened and based on that start blinkLED inside the main loop.
I also recommend you to use millis() function for an unblocking delay inside blinkLED function (e.g when you want to stop blinking while the door is closed).
const byte LED_Red = 13;
const byte DOOR_SENSOR = 2; // magnetic door sensor pin
// flag to check door is opened
volatile bool isOpened = false;
//flag to check already blinked
volatile bool isBlinked = false;
void setup()
{
Serial.begin(9600);
pinMode(LED_Red, OUTPUT);
pinMode(DOOR_SENSOR, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), DoAction, CHANGE);
}
void DoAction()
{
if (digitalRead(DOOR_SENSOR) == HIGH)
{
//Serial.println("Opened");
isOpened = true;
}
else
{
isOpened = false;
isBlinked = false;
//Serial.println("Closed");
}
}
void blinkLED(int repeats, int time)
{
byte LEDState = LOW;
unsigned long delay_start = millis();
for (int i = 0; i < 2 * repeats; i++)
{
//Toggle LED state
if (LEDState == HIGH)
LEDState = LOW;
else
LEDState = HIGH;
// set value
digitalWrite(LED_Red, LEDState);
// some unblocking delay
while (millis() - delay_start < time)
{
// return if door is closed
if (!isOpened)
{
// turn off LED
digitalWrite(LED_Red, LOW);
return;
}
}
delay_start = millis();
}
isBlinked = true;
}
void loop()
{
// Check isBlinked beacue don't want to blink again until door is closed
if (isOpened && !isBlinked)
{
blinkLED(10, 500);
}
}

Arduino fan controller code issues (LM35)

I got an issue with the PWM signal on the fan, it actually gets to 100% right away when it hits 21°C when it should be on 10%. I don't think it's a circuit issue, so any suggestions on the code ? I am pretty sure the problem is somewhere at the Map function, just can't seem to figure it out.
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
int tempPin = A1; // the output pin of LM35
int fan = 11; // the pin where fan is
int led = 8; // led pin
int temp;
int tempMin = 20; // the temperature to start the fan
int tempMax = 30; // the maximum temperature when fan is at 100%
int fanSpeed;
int fanLCD;
void setup() {
pinMode(fan, OUTPUT);
pinMode(led, OUTPUT);
pinMode(tempPin, INPUT);
lcd.begin(16,2);
Serial.begin(9600);
}
void loop() {
temp = readTemp(); // get the temperature
if(temp < tempMin) { // if temp is lower than minimum temp
fanSpeed = 0; // fan is not spinning
digitalWrite(fan, LOW);
}
if((temp >= tempMin) && (temp <= tempMax)) { // if temperature is higher than minimum temp
fanSpeed = map(temp, tempMin, tempMax, 115, 255); // the actual speed of fan
fanLCD = map(temp, tempMin, tempMax, 0, 100); // speed of fan to display on LCD
analogWrite(fan, fanSpeed); // spin the fan at the fanSpeed speed
}
if(temp > tempMax) { // if temp is higher than tempMax
digitalWrite(led, HIGH); // turn on led
} else { // else turn off led
digitalWrite(led, LOW);
}
lcd.print("TEMP: ");
lcd.print(temp,1); // display the temperature
lcd.print("C ");
lcd.setCursor(0,1); // move cursor to next line
lcd.print("FAN: ");
lcd.print(fanLCD); // display the fan speed
lcd.print("%");
delay(500);
lcd.clear();
}
int readTemp() { // get the temperature and convert it to celsius
temp = analogRead(tempPin);
return (temp * 0.48828125)-48;
}
Ok so apparently there was a problem with this specific pin, i tried another one (PWM), and it worked perfectly!

Resources