Transférer les fichiers vers 'arduino_proto_threads/tp_serre'

Code associé au TP µserre
This commit is contained in:
JeArz 2021-10-08 09:23:11 +02:00
parent ee155fe7d6
commit d983a61d51
3 changed files with 337 additions and 0 deletions

View File

@ -0,0 +1,76 @@
#ifndef __PT_H__
#define __PT_H__
typedef unsigned short lc_t;
#define LC_INIT(s) s = 0; // LC_INIT
#define LC_RESUME(s) switch(s) { case 0: // LC_RESUME
#define LC_SET(s) s = __LINE__; case __LINE__: // LC_SET line
#define LC_END(s) } // LC_END
struct pt { lc_t lc; };
#define PT_WAITING 0
#define PT_YIELDED 1
#define PT_EXITED 2
#define PT_ENDED 3
#define PT_INIT(pt) LC_INIT((pt)->lc) // INIT
#define PT_THREAD(name_args) char name_args // THREAD
#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) // BEGIN
#define PT_END(pt) LC_END((pt)->lc); \
PT_YIELD_FLAG = 0; \
PT_INIT(pt); return PT_ENDED; } // END
#define PT_WAIT_UNTIL(pt, condition) \
do { \
LC_SET((pt)->lc); \
if(!(condition)) { \
return PT_WAITING; \
} \
} while(0) // WAIT_UNTIL
#define PT_WAIT_WHILE(pt, cond) \
PT_WAIT_UNTIL((pt), !(cond)) // WAIT_WHILE
#define PT_WAIT_THREAD(pt, thread) \
PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) // WAIT_THREAD
#define PT_SPAWN(pt, child, thread) \
do { \
PT_INIT((child)); \
PT_WAIT_THREAD((pt), (thread)); \
} while(0) // SPAWN
#define PT_RESTART(pt) \
do { \
PT_INIT(pt); \
return PT_WAITING; \
} while(0) // RESTART
#define PT_EXIT(pt) \
do { \
PT_INIT(pt); \
return PT_EXITED; \
} while(0) // EXIT
#define PT_SCHEDULE(f) ((f) < PT_EXITED) // SCHEDULE
#define PT_YIELD(pt) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if(PT_YIELD_FLAG == 0) { \
return PT_YIELDED; \
} \
} while(0) // YIELD
#define PT_YIELD_UNTIL(pt, cond) \
do { \
PT_YIELD_FLAG = 0; \
LC_SET((pt)->lc); \
if((PT_YIELD_FLAG == 0) || !(cond)) { \
return PT_YIELDED; \
} \
} while(0) // YIELD_UNTIL
// checked for n calls in a thread : seems OK
#define PT_DELAY(pt, ms) \
do { \
static unsigned long _PTTTL_ ; \
_PTTTL_ = millis() + (unsigned int)(ms); \
PT_WAIT_UNTIL((pt), (millis() > _PTTTL_)); \
} while(0) // DELAY
#define PT_SYNC(pt, mark, ms) \
do { \
PT_WAIT_UNTIL((pt), (millis() - (mark) > (ms) )); \
} while(0) // SYNC
#endif /* __PT_H__ */

View File

@ -0,0 +1,103 @@
/*------------------------------------------------------------------*/
/* Projet: Dev Tools */
/* File : serialTrace.h */
/* Author: user@W500 08/28/20 */
/*------------------------------------------------------------------*/
// RCS CI/CO : Cx v v, terminate log : CcCc, view log : Cx v l
// TODO: all this should be in a class or a singleton class
// TODO: strings should be in Flash 32kb code
// #include <avr/pgmspace.h>
#ifndef __SERIALTRACE_H__
#define __SERIALTRACE_H__
extern char *__brkval;
unsigned long freeMemory() {
char top;
return &top - (__brkval ? __brkval : __malloc_heap_start);
}
void retard(unsigned long ms, int mini) {
#ifndef TEST
delay(ms);
#else
delay(mini);
#endif
}
// functions used for I/O using serial monitor
#ifndef IHM // if IHM undefined then just empty functions.
// So users don't need to change code, just define/undefine IHM.
// A bit of a waste, but main purpose is testing.
bool ttyAskN ( String prompt ) {}
bool ttyAskY ( String prompt ) {}
char ttyGetChar ( String prompt ) {}
int ttyGetInt ( String prompt ) {}
void ttyPutInt ( String prompt, int num ) {}
void ttyPutMem ( ) {}
void ttyPutStr ( String txt ) {}
void ttyPutUin ( String prompt, unsigned int num ) {}
void ttyPutFloat ( String prompt, float num ) {}
void ttySetIHM ( long baud ) {}
void ttyWipe ( short lines ) {}
#else
void ttySetIHM(long baud) {
Serial.begin(baud); // WIP check if baud in correct values ?
for (int i=0;i<10;i++) Serial.print("\n") ;
}
void ttyPutStr(String txt) { Serial.println(txt);
}
void ttyPutMem() {
char buf[32];
unsigned long octets = freeMemory();
int k = octets / 1024 ; int o = octets % 1024;
sprintf(buf, "SRAM: %dKo%d free",k,o);
Serial.println (buf) ;
}
void ttyPutInt(String prompt, int num ) {
char buf[64];
sprintf(buf, "%s %d", prompt.c_str(), num ) ;
Serial.println (buf) ;
}
void ttyPutUin(String prompt, unsigned int num ) {
char buf[64];
sprintf(buf, "%s %d", prompt.c_str(), num ) ;
Serial.println(buf) ;
}
int ttyGetInt(String prompt) {
Serial.println(prompt);
while (Serial.available()==0) {} //Wait for user input
String val=Serial.readString();
return val.toInt();
}
void ttyPutFloat ( String prompt, float num ) {
Serial.print(prompt);
Serial.println (num) ;
}
void ttyPutFloatRound ( String prompt, float num ) {
char buf[64];
sprintf(buf, "%s %d", prompt.c_str(), int(num) ) ;
Serial.println (buf) ;
}
char ttyGetChar(String prompt) {
Serial.println(prompt);
while (Serial.available()==0) {} //Wait for user input
return Serial.read();
}
bool ttyAskY(String prompt){
byte R = 223 & (byte)ttyGetChar(prompt);
if ('Y' == R ) return true;
else return false ;
}
bool ttyAskN(String prompt){
byte R = 223 & (byte)ttyGetChar(prompt);
if ('N' == R ) return true;
return false ;
}
void ttyWipe (short lines) {
//const short ESC=27 ; KO in Arduino serial monitor, works with others tty
// Serial.write(ESC); Serial.print("[2J"); // cls
// Serial.write(ESC); Serial.print("[H"); // cursor to home
while (lines--) Serial.print("\n") ; // somehow overkill !
}
#endif // IHM
#endif // __SERIALTRACE_H__

View File

@ -0,0 +1,158 @@
/* Si la température est < 15°C, un cycle de chauffe.
Si la température > 25 °C, le ventilateur tourne en proportion.
Si lHumidité < 50%, un cycle arrosage.
Si lHumidité >70 %, le ventilateur tourne en proportion
*/
#define JAUNE 13 //
#define BLEU 12 //
#define ROUGE 11 //
#define VERTE 9 //
#define APVCC 2 //
#define APGND 6 //
#define AP_H A0 //
#define AP_T A1 //
#define IHM
#include "serialTrace.h" // infos / trace to serial monitor
#include "pt.h"
static struct pt ptT, ptH, ptV, ptC, ptE, ptN, ptA; // proto threads
int temp=0; int humi=0;
bool alarme = false; int nb_cycles = 0;
void log_acqui(char * msg, int va);
void ledPWM(int led, int ratio) {
int val=constrain(ratio,0,254); // limit to values [0..254]
analogWrite(led, val);
}
int acquis(int broche, int vmin, int vmax) {
// WIP
int val ;
val=analogRead(broche); // 1024 pts, 0 < U < 5V ==> 0 < val < 1023
return map (val, 0, 1023, vmin, vmax ) ;
}
static int ptTemp(struct pt *pt, int repit) {
static unsigned long ttl = 0;
PT_BEGIN(pt);
while(1) {
ttl = millis() + repit ;
PT_WAIT_UNTIL(pt, millis() > ttl);
temp = acquis(AP_T, 0, 50); // pour ptHumi on a : humi = acquis(AP_T, 20, 80);
ttyPutInt ("temp: ", temp);
}
PT_END(pt);
}
static int ptHumi(struct pt *pt, int repit) {
static unsigned long ttl = 0;
PT_BEGIN(pt);
while(1) {
ttl = millis() + repit;
PT_WAIT_UNTIL(pt, millis() > ttl);
humi = acquis(AP_H, 20, 80);
ttyPutInt ("humi: ",humi);
}
PT_END(pt);
}
static int ptAlarme (struct pt *pt, int duree){
static unsigned long ttl;
PT_BEGIN(pt);
while (alarme) {
ttl = millis() + duree;
PT_WAIT_UNTIL(pt, millis() > ttl);
digitalWrite(VERTE, !digitalRead(VERTE));
}
PT_END(pt);
}
static int ptNiveau(struct pt *pt){
static int nb_old = 0; int ratio;
PT_BEGIN(pt);
while (!alarme) {
nb_old = nb_cycles;
ratio = map(nb_cycles, 0, 100, 254, 0);
ledPWM(VERTE, ratio);
PT_WAIT_UNTIL(pt, nb_cycles > nb_old ); // attente nouvel arrosage
}
PT_END(pt);
}
static int ptChauffe(struct pt *pt, int actif, int inactif ){
static unsigned long ttl = 0;
PT_BEGIN(pt);
while (1) {
PT_WAIT_UNTIL(pt, temp < 15);
digitalWrite(JAUNE, HIGH);
ttl = millis() + actif ;
PT_WAIT_UNTIL (pt, millis() > ttl);
digitalWrite(JAUNE, LOW);
ttl = millis() + inactif ;
PT_WAIT_UNTIL (pt, millis() > ttl);
}
PT_END(pt);
} // Chauffe
static int ptEau(struct pt *pt, int actif, int inactif ) {
static unsigned long ttl = 0;
PT_BEGIN(pt);
while (!alarme) {
PT_WAIT_UNTIL(pt, humi < 50);
digitalWrite(BLEU, HIGH);
ttl = millis() + actif ;
nb_cycles++;
alarme = ( nb_cycles > 100);
PT_WAIT_UNTIL (pt, millis() > ttl);
digitalWrite(BLEU, LOW);
ttl = millis() + inactif ;
PT_WAIT_UNTIL (pt, millis() > ttl);
}
PT_END(pt);
} // Eau
static int ptVenti(struct pt *pt) {
static int temp_old = 0, humi_old = 0; int t_ratio=0, h_ratio = 0, i ;
static unsigned long ttl = 0;
PT_BEGIN(pt);
while (1) {
if (temp < 25 && humi < 70) digitalWrite(ROUGE, LOW);
PT_WAIT_UNTIL(pt, temp > 25 || humi > 70);
temp_old = temp;
humi_old = humi ;
if (temp > 25) t_ratio = map(temp, 0, 50, 0,254);
if (humi > 70) h_ratio = map(humi, 30, 100, 0,254);
i = max(t_ratio , h_ratio );
ledPWM(ROUGE, i) ;
PT_WAIT_UNTIL(pt, temp != temp_old || humi != humi_old );
}
PT_END(pt);
} // Ventilateur
void initIO() {
pinMode(ROUGE, OUTPUT); analogWrite(ROUGE, 0);
pinMode(JAUNE, OUTPUT); pinMode(BLEU, OUTPUT);
digitalWrite(JAUNE, LOW); digitalWrite(BLEU, LOW) ;
pinMode(VERTE, OUTPUT); analogWrite(VERTE, 254); // at max
pinMode(APVCC, OUTPUT); pinMode(APGND, OUTPUT);
digitalWrite(APVCC, HIGH); digitalWrite(APGND, LOW);
}
void setup() {
int val;
initIO(); // Setup: set LEDs & pots
// static struct pt ptT, ptH, ptV, ptC, ptE, ptN, ptA ;
PT_INIT(&ptT); PT_INIT(&ptH); PT_INIT(&ptV); PT_INIT(&ptC);
PT_INIT(&ptE); PT_INIT(&ptN); PT_INIT(&ptA);
ttySetIHM(9600);
Serial.println(F("\nLog de " __FILE__ " du " __DATE__));
val=analogRead(1);
ttyPutInt("Raw Temp = ",val);
val=analogRead(0);
ttyPutInt("Raw humi = ",val);
temp = acquis(1, 0, 100);
ttyPutInt("Temp = ",temp);
humi = acquis(0, 0, 100);
ttyPutInt("Humi = ",humi);
}
void loop() {
ptTemp(&ptT,2000); // acquisition t° chaque 200ms
ptHumi(&ptH,4000); // acquisition % chaque 500ms
ptVenti(&ptV); // pilotage ventilation (LED Rouge)
ptChauffe(&ptC,5,10); // pilotage chauffage de 3s et inactivité de 3s (LED Jaune)
ptEau(&ptE,3,20); // pilotage arrosage de 3s et inactivité de 5s (LED Bleu)
ptNiveau(&ptN); // affichage niveau deau, PWM Verte de 254 à 0 (LED Verte)
ptAlarme(&ptA,500); // alarme réserve vide , clignote à 1Hz (LED Verte)
}