Hello, I am currently carrying out a 8 week internship assignment where I have to automate a door for a solar-powered chicken coop, and my 6th week is almost over.
I am currently using an Arduino UNO board, a 2 channel relay module, a solar cell, a 3.7V lipo battery and a LCD display with buttons.
The door is opened and closed using a motor that turns in either direction and rolls or unwinds a wire that opens or closes the door.
I would like to perform manual door operation: when pressing a test button, the door must close to the bottom sensor, stay closed for 3s seconds then open up to the top sensor.
First of all, here is the assembly I made with my breadboard. It includes 1 resistor of 1 Ohm, 2 resistors of 10k Ohms, a rectifier diode to prevent the battery from discharging, and a 100 µF and 25V capacitor:
On the first picture is also another test board related to limit switches, but I am not using it in the program yet.
In the third one, in red, this is where I connecte the lipo battery.
Here then is the program that I use for my editing:
//moteur + relais + LCD + cellule + bouton (afficheur)
// LCD Keypad Shield
#include <LiquidCrystal.h>
// Création de l'objet lcd (avec les différents ports numériques qu'il utilise)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//variables
int lcd_key = 0;
int adc_key_in = 0;
//constantes
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
const uint8_t RelayPin1 = 2; //le port numérique D2 est connecté au relais 1
const uint8_t RelayPin2 = 3; //le port numérique D3 est connecté au relais 2
static uint8_t state = 0;
void setup()
{
// On met les pin de chaque relais en sortie
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
// Initialise la communication avec le PC
Serial.begin(9600);
lcd.begin(16, 2); // Démarrage de l'écran
lcd.setCursor(0,0); // Positionnement du curseur au début
lcd.print("Mesure tension"); // Message
}
void loop()
{
lcd_key = read_LCD_buttons(); // Lecture des touches
// Sous traite les différentes tâches
task_moteur1();
task_moteur2();
switch (lcd_key) // Action en cas de touche pressée
{
case btnRIGHT: //en appuyant sur le bouton RIGHT
{
if (state == 0){
state = 1; //on incrémente la variable state de 1
}
break;
}
}
}//loop
void task_moteur1() //permet de prendre des mesures de tension
{
static uint32_t
timePrint;
uint32_t timeNow = millis();
if( (timeNow - timePrint) >= 250ul )
{
timePrint = timeNow;
// Transforme la mesure (nombre entier) en tension via un produit en croix
int valeur1 = analogRead(A1); // Mesure la tension aux bornes de la cellule solaire
int valeur2 = analogRead(A2); // Mesure la tension consommée par le moteur
float tension1 = (float)valeur1 * (5.0 / 1023.0);
float tension2 = (float)valeur2 * (5.0 / 1023.0);
// Affiche la mesure de la tension sur l'écran LCD et attends 250 ms
lcd.setCursor(0,1); // Positionnement du curseur début de ligne
lcd.print("L:");
lcd.print(tension1); //affiche la tension de la cellule solaire sur l'écran LCD
lcd.print(" M:");
lcd.print(tension2); //affiche la tension du moteur sur l'écran LCD
lcd.print(" S");
lcd.print(state); //affiche la valeur de l'état du moteur
Serial.println(state);
//Serial.println(RelayPin1, OUTPUT);
//Serial.println(RelayPin2, OUTPUT);
}//if
}//task_moteur1
void task_moteur2() //joue avec les états des relais pour faire tourner le moteur
{
static uint32_t
timeRelays;
uint32_t timeNow = millis();
switch( state )
{
// case 0:
// // Au démarrage, le moteur est en pause...
// digitalWrite(RelayPin1, HIGH);
// digitalWrite(RelayPin2, HIGH);
case 1:
// Puis, on allume l'un des relais alors que l'autre est éteint...
digitalWrite(RelayPin1, LOW);
digitalWrite(RelayPin2, HIGH);
//delay(10000);
timeRelays = timeNow;
state++;
// lcd.setCursor(1,14); // Positionnement du curseur début de ligne
// lcd.print("S");
// lcd.print(state); //affiche la valeur de l'état du moteur
break;
case 2:
if( (timeNow - timeRelays) >= 5000ul )
{
// On éteint ensuite le ler relais: le moteur est en pause pendant 3 secondes...
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, HIGH);
//delay(5000);
timeRelays = timeNow;
state++;
// lcd.setCursor(1,14); // Positionnement du curseur début de ligne
// lcd.print("S");
// lcd.print(state); //affiche la valeur de l'état du moteur
}//if
break;
case 3:
if( (timeNow - timeRelays) >= 3000ul )
{
// Puis on allume l'autre...
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, LOW);
//delay(10000);
timeRelays = timeNow;
state++;
// lcd.setCursor(1,14); // Positionnement du curseur début de ligne
// lcd.print("S");
// lcd.print(state); //affiche la valeur de l'état du moteur
}//if
break;
case 4:
if( (timeNow - timeRelays) >= 5000ul )
{
// Enfin, on éteins le 2ème relais: le moteur est encore en pause pendant 3 secondes...
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, HIGH);
//delay(5000);
timeRelays = timeNow;
state++;
// lcd.setCursor(1,14); // Positionnement du curseur début de ligne
// lcd.print("S");
// lcd.print(state); //affiche la valeur de l'état du moteur
}//if
break;
case 5:
if( (timeNow - timeRelays) >= 3000ul )
{
//after 5 seconds go back to state zero
state = 0;
// lcd.setCursor(1,14); // Positionnement du curseur début de ligne
//lcd.print("S");
//lcd.print(state); //affiche la valeur de l'état du moteur
}//if
break;
}//switch
}//task_moteur2
// Fonction de lecture des touches
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // Lecture du port analogique
// Les valeurs qui suivent doivent être adaptées au shield
if (adc_key_in > 1000) return btnNONE; // En principe 1023 quand aucune touche n'est pressée
if (adc_key_in < 50) return btnRIGHT; // 0
if (adc_key_in < 195) return btnUP; // 99
if (adc_key_in < 380) return btnDOWN; // 255
if (adc_key_in < 555) return btnLEFT; // 409
if (adc_key_in < 790) return btnSELECT; // 640
return btnNONE;
}
Originally, the loop of the closing and then opening program was carried out when I directly connected the battery to my assembly. But now I want the loop to start, where after the battery is already plugged in I press the RIGHT button on the LCD display to start the loop.
There is also a state variable, initially assigned to 0, which indicates the state of the motor according to the states of the relays, responsible for turning it from one direction to the other to close or open the door.
I then uploaded my program.
Result: Strangely, by connecting the lipo battery to 1 other pair of neighboring holes instead of the usual one (see photo 3), the screen lights up without directly starting the loop.
You just have to press the button to start the loop, and the value of State that is displayed on the LCD screen varies well depending on the state of the motor. If you connect the battery to the usual pair of holes used to power most fixtures, the door opens immediately.
However, by dint of testing the 2 locations, the results are random. It looks like it depends on how hard you push the lipo battery terminals into the test board.
Even with the capacitor supposed to eliminate noise, the problem still persists. Could someone tell me if the problem is with my program? or my assembly? Answer me quickly please