od OndraTT » úte 06 dub, 2021 7:01 pm
Kolegové, prosím o radu s naprogramováním systému pro řízení přejezdu (bez závor) s Arduinem v ANALOGOVÉM kolejišti (PWM napájení).
Původně jsem vycházel z příkladů na Vejrov.cz a snažím se již delší dobu předělat zde uváděné programy Arduino 5 a Arduino 8 pro přejezd bez závor, řízený Arduinem na dvojkolejnou trať a nedaří se a nedaří. Ambicí ještě k tomu bylo předělat to na pouze na dva IR senzory na každé koleji, ale tam jsem asi nejvíc narazil.
Po diskuzi s autorem jsem změnil systém z IR senzorů na snímání proudu do odděleného úseku s přejezdem pomocí modulu ACS712 (Hallova sonda) bez použití IR senzorů.
Zapojení je jednoduché, napájení úseku s přejezdem je přes tento senzor, jinak nic jiného.
Ve chvíli kdy se v úseku objeví lokomotiva, má odběr, senzor detekuje proud a to splní podmínku pro výstražné červené světlo. Když úsek opustí, opět se rozsítí bílá. Dvojkolejnost přejezdu je v takové chvíli jednoduše řešitelná, prostě se bude odběr kontrolovat ve dvou větvích.
Základní program takto funguje pěkně, co jsem ale nevyřešil je situace kdy lokomotiva v úseku zastaví. Zkoušel jsem to přes variantu měření napětí na kolejích, problém je se smyčkovitostí programu, kdy se musí srovnávat aktuální měření se stavem z minula - a to se mi nepodařilo. Vždycky se nějak zacyklím v logice a syntaxi a neprolomím to.
Níže je zjednodušená forma programu, finální by byla pro dvě koleje a taky pro vyzvánění s PCM samplem (vyzkoušeno funkční)
Dokázal by někdo navrhnout úpravu té logiky aby bylo to zastavení lokomotivy správně detekováno a stav zůstal obsazeno, dokud lokomotiva úsek neopustí? Díky
const int analogIn = A0; // vstup pro usek prejezdu
const int analogV = A1; // vstup pro napajeci napeti
int konstanta = 185; // konstanta pro přepočet naměřeného napětí na proud
int offset = 2500; // proměnná pro nastavení offsetu, polovina Vcc
int red1 = 2; // vystup cervene svetlo 1
int red2 = 3; // vystup cervene svetlo 2
int white1 = 4; // vystup bile svetlo
int stav = 0; // stav obsazeni prejezdu
int ledDelay = 400;
bool wait = true;
double zdroj = 0; //napajeci napeti
double proud = 0; //proud do useku prejezdu
int analog = 0;
double napeti = 0; // napeti na Hallove sonde
double soucet = 0; // vypocet proudu
void setup(){
pinMode(analogIn, INPUT);
pinMode(analogV, INPUT);
pinMode(red1, OUTPUT);
pinMode(red2, OUTPUT);
pinMode(white1, OUTPUT);
}
void loop()
{
for(int i=0;i<100;i++) // provedení stovky měření pro ustálení výsledku
{
// načtení hodnoty analogovych vstupu
analog = analogRead(analogIn);
zdroj = analogRead(analogV);
// přepočet napětí na proud
napeti = (analog * 5000.0) / 1023.0;
proud = (napeti - offset) / konstanta;
// uložení výsledku pro následné zprůměrování
soucet += proud;
}
proud = (soucet/100);// výpočet průměru ze stovky měření
if (proud < 0.05 || proud > 0.05)
{
stav = 0; // usek prejezdu neni obsazen
}
if (proud > 0.05 || proud < -0.05)
{
stav = 1; // usek prejezdu je obsazen
}
if (stav == 0)
{
if (wait == true){delay (1000);} //delay - délka zpoždění bílého světla 6000 = 6 sekund - max 32 000 = 32 sekund
wait = false;
digitalWrite(white1, HIGH);
delay(ledDelay);
digitalWrite(white1, LOW);
delay(ledDelay);
}
else
{
wait = true;
delay(10);
digitalWrite(red1, HIGH);
delay(ledDelay);
digitalWrite(red1, LOW);
delay(100);
digitalWrite(red2, HIGH);
delay(ledDelay);
delay(200);
digitalWrite(red2, LOW);
}