Ovládání výstupů - sériová linka
Re: Ovládání výstupů - sériová linka
Odpoledne to testnu Moc díky.
k tomu GND. Od řídící jednotky (garáž) vedou dvě žíly jako sériová linka a dvě jako tvrdý zdroj k napájení ventilů. tak jsem to použil společně k napájení obou Arduin. Mám tam jednu žílu navíc, tak tou mohu spojit společně GND.
P.S.
Napsal jsem Jéžiškovi o knihu Průvodce světem Arduina, tak to postupně pročítám a hledám různé cesty. Je to asi první kniha o programování, která mě tak chytla. Nejde o to, aby to "jen" fungovalo, ale abych to pochopil a uměl příště použít.
k tomu GND. Od řídící jednotky (garáž) vedou dvě žíly jako sériová linka a dvě jako tvrdý zdroj k napájení ventilů. tak jsem to použil společně k napájení obou Arduin. Mám tam jednu žílu navíc, tak tou mohu spojit společně GND.
P.S.
Napsal jsem Jéžiškovi o knihu Průvodce světem Arduina, tak to postupně pročítám a hledám různé cesty. Je to asi první kniha o programování, která mě tak chytla. Nejde o to, aby to "jen" fungovalo, ale abych to pochopil a uměl příště použít.
Re: Ovládání výstupů - sériová linka
Ano, je potřeba mít spojené země přijímacího a vysílacího Arduina. Nemusí být spojené pokud bys používal třeba RS485 ale Arduino má RS232 TTL. Jestli máš ale Arduina napájené stejným zdrojem tak už země spojené máš.
Re: Ovládání výstupů - sériová linka
Axamith má sice obě desky napájené stejným zdrojem, ale střídavým.
Usměrňovače má až na těch deskách.
Usměrňovače má až na těch deskách.
Re: Ovládání výstupů - sériová linka
Po těžkých bojích, mnoho slepých uličkám, pročítání manuálů k jednotlivým funkcím ... jsem se prokousal k funkčnímu výsledku. Jako vedlejší produkt tohoto snažení je odpálený USB/TTL programátor
Mimo jiné mi velmi pomohl AstroMiK a jeho ukázkový kód. Jak jsem postupně pochopil, ani ten nebyl bez chyby, hlavně ten na přijímací straně, ale už to byla cesta, která vedla k cíli. Dále mi hodně pomohl popis knihovny Serial http://docs.uart.cz/docs/serial/
Kód vysílací strany zůstal v podstatě beze změn, pouze jsem původní proměnnou nahradil hodnotou 99. Hodnota nula (vypnutý stav) se při přepínání vstupů generovala po lince tak trochu náhodně, tak jsem ji nahradil nenulovým číslem, které mě zrovna napadlo.
Takže vypnutý stav = 99
vstup 1 = 100 (99+1)
vstup 2 = 101(99+2)
vstup 3 = 102 (99+3)
vstup 4 = 103 (99+4)
vstup 5 = 104 (99+5)
vstup 6 = 105 (99+6)
Přijímací stranu jsem postupně zcela přepracoval. Je nutné přijímat číslo, pokud to tak potřebuji
Dále jsem postupně řešil podmínky, výsledný kód se mi jeví jako nevhodnější. Zcela jsem odstranil počítání bytů v bufferu a zaměřil se jen na čísla. připadalo mi to jednodušší a srozumitelnější. Možná jsem objevil Ameriku, ale doposud jsem nevěděl, že do Arduina mohu posílat po ser. lince data přes ser. monitor. Hodně to ulehčuje práci. Tak jsem odladil vysílací i přijímací část samostatně a následně "jen" propojil a ověřil funkčnost. Odstranil jsem oddělené napájení, udělal jedno společné + Rx, Tx.
Vysílací strana:
Přijímací strana:
Děkuji všem, kdo mě nakopli správným směrem, doufám, že takto podrobný popis někdy někomu také pomůže.
Mimo jiné mi velmi pomohl AstroMiK a jeho ukázkový kód. Jak jsem postupně pochopil, ani ten nebyl bez chyby, hlavně ten na přijímací straně, ale už to byla cesta, která vedla k cíli. Dále mi hodně pomohl popis knihovny Serial http://docs.uart.cz/docs/serial/
Kód vysílací strany zůstal v podstatě beze změn, pouze jsem původní proměnnou
Kód: Vybrat vše
byte vysilana_hodnota =0;
Takže vypnutý stav = 99
vstup 1 = 100 (99+1)
vstup 2 = 101(99+2)
vstup 3 = 102 (99+3)
vstup 4 = 103 (99+4)
vstup 5 = 104 (99+5)
vstup 6 = 105 (99+6)
Přijímací stranu jsem postupně zcela přepracoval. Je nutné přijímat číslo, pokud to tak potřebuji
Kód: Vybrat vše
while (Serial.available()) { // cteni ser. linky
byte vstup = Serial.parseInt(); // kdyz se na seriovem portu objevi nejaka ciselna data ...
Vysílací strana:
Kód: Vybrat vše
//prirazeni vstupu k pinu
byte int_1 = 4; //vstup 1
byte int_2 = 3; //vstup 2
byte int_3 = 5; //vstup 3
byte int_4 = 6; //vstup 4
byte int_5 = 7; //vstup 5
byte int_6 = 8; //vstup 6
void setup()
{
Serial.begin(9600);// rychlost ser. linky
//definice pinu - vstup
pinMode(int_1, INPUT_PULLUP); // Pull-Upy jsem tam pridaval jen kvuli testovani
pinMode(int_2, INPUT_PULLUP);
pinMode(int_3, INPUT_PULLUP);
pinMode(int_4, INPUT_PULLUP);
pinMode(int_5, INPUT_PULLUP);
pinMode(int_6, INPUT_PULLUP);
}
void loop(void)
{
byte vysilana_hodnota = 99;
// sepnuty kontakt na GND se odesila jako binarni "1"
if (digitalRead(int_1) == LOW) vysilana_hodnota += 1;
if (digitalRead(int_2) == LOW) vysilana_hodnota += 2;
if (digitalRead(int_3) == LOW) vysilana_hodnota += 3;
if (digitalRead(int_4) == LOW) vysilana_hodnota += 4;
if (digitalRead(int_5) == LOW) vysilana_hodnota += 5;
if (digitalRead(int_6) == LOW) vysilana_hodnota += 6;
// Serial.println(vysilana_hodnota);
// Serial.write(vysilana_hodnota);
delay(1000); // dostatecne dlouha doba, aby prijimaci Arduino melo cas prijata data zpracovat a nezahltil se mu prijimaci buffer
}
Kód: Vybrat vše
//prirazeni vystupu k pinu
int out_1 = 7; //vystup 1-pin 7
int out_2 = 6; //vystup 2-pin 6
int out_3 = 5; //vystup 3-pin 5
int out_4 = 4; //vystup 4-pin 4
int out_5 = 3; //vystup 5-pin 3
int out_6 = 2; //vystup 6-pin 2
void setup() {
//definice vystupu
pinMode(out_1, OUTPUT);
pinMode(out_2, OUTPUT);
pinMode(out_3, OUTPUT);
pinMode(out_4, OUTPUT);
pinMode(out_5, OUTPUT);
pinMode(out_6, OUTPUT);
//reset vystupu
digitalWrite(out_1, HIGH);
digitalWrite(out_2, HIGH);
digitalWrite(out_3, HIGH);
digitalWrite(out_4, HIGH);
digitalWrite(out_5, HIGH);
digitalWrite(out_6, HIGH);
Serial.begin(9600); //seriova linka
}
void loop()
{
while (Serial.available()) { // cteni ser. linky
byte vstup = Serial.parseInt(); // kdyz se na seriovem portu objevi nejaka ciselna data ...
// Serial.println(vstup); //vypis promenne na ser. monitor
if(vstup == 100){ // vystup 1 ON
digitalWrite(out_1, LOW);
}
if(vstup == 101){ // vystup 2 ON
digitalWrite(out_2, LOW);
}
if(vstup == 102){ // vystup 3 ON
digitalWrite(out_3, LOW);
}
if(vstup == 103){ // vystup 4 ON
digitalWrite(out_4, LOW);
}
if(vstup == 104){ // vystup 5 ON
digitalWrite(out_5, LOW);
}
if(vstup == 105){ // vystup 6 ON
digitalWrite(out_6, LOW);
}
if(vstup == 99) { // vystupy 1-6 OFF
digitalWrite(out_1, HIGH);
digitalWrite(out_2, HIGH);
digitalWrite(out_3, HIGH);
digitalWrite(out_4, HIGH);
digitalWrite(out_5, HIGH);
digitalWrite(out_6, HIGH);
}
}
}
Re: Ovládání výstupů - sériová linka
Jestli jsi přijímal nějaká náhodná čísla při vysílání 0, tak to bude (pravděpodobně) způsobené rušením přenosu.
Není prostě důvod, proč by s číslem 0 měl být problém, ale číslo 99 je v pořádku.
POZOR!
Ten tvůj způsob počítání proměnné "vysilana_hodnota" bude fungovat jen v případě, že bude sepnutý pouze jeden vstupní pin.
Pokud by se někdy stalo, že se ti sepne víc vstupních pinů zároveň, získáš nesmyslné údaje.
Například když se sepne 2. a 3. vstup zároveň, tak se ti komunikací odešle číslo 104 (99 + 2 + 3).
Tohle číslo se na přijímací straně dekóduje tak, že se sepne výstup "out_5".
To už by bylo skoro lepší tu proměnnou nastavovat takto:
Pak by se v připadě sepnutí více vstupů zároveň nastavila "vysilana_hodnota" na nejvyšší z těch sepnutých vstupů.
(třeba při sepnutí 2. a 4. vstupu se nastaví proměnná na 103, což se dekóduje na přijímači jako 4. výstup)
V tom mém původním kódu tohle nebezpečí nehrozí.
Tam když se sepne najednou několik vstupů, tak se dají zase jednoduše všechny zpátky rozkódovat na přijímací straně.
Není prostě důvod, proč by s číslem 0 měl být problém, ale číslo 99 je v pořádku.
POZOR!
Ten tvůj způsob počítání proměnné "vysilana_hodnota" bude fungovat jen v případě, že bude sepnutý pouze jeden vstupní pin.
Pokud by se někdy stalo, že se ti sepne víc vstupních pinů zároveň, získáš nesmyslné údaje.
Například když se sepne 2. a 3. vstup zároveň, tak se ti komunikací odešle číslo 104 (99 + 2 + 3).
Tohle číslo se na přijímací straně dekóduje tak, že se sepne výstup "out_5".
To už by bylo skoro lepší tu proměnnou nastavovat takto:
Kód: Vybrat vše
byte vysilana_hodnota = 99;
if (digitalRead(int_1) == LOW) vysilana_hodnota = 100;
if (digitalRead(int_2) == LOW) vysilana_hodnota = 101;
if (digitalRead(int_3) == LOW) vysilana_hodnota = 102;
if (digitalRead(int_4) == LOW) vysilana_hodnota = 103;
if (digitalRead(int_5) == LOW) vysilana_hodnota = 104;
if (digitalRead(int_6) == LOW) vysilana_hodnota = 105;
(třeba při sepnutí 2. a 4. vstupu se nastaví proměnná na 103, což se dekóduje na přijímači jako 4. výstup)
V tom mém původním kódu tohle nebezpečí nehrozí.
Tam když se sepne najednou několik vstupů, tak se dají zase jednoduše všechny zpátky rozkódovat na přijímací straně.
Re: Ovládání výstupů - sériová linka
Já budu spínat pouze jeden vstup. Jde o to, že závlaha má několik okruhů a každý jede v jinou dobu (mezera cca 15 minut mezi sepnutími), dělá se to tak kvůli omezení nadměrného odběru vody ze studny a minimalizování kolísání hladiny. Ta závlaha si umí vzít dost vody, takže kolísající hladina by strhávala drobné písky a zanášel by se vrt (doporučení hydrgeologa). I čerpadlo by zřejmě neužilo několik okruhů najednou.
Ano, máš pravdu, bylo by jistější posílat čísla, která svým součtem nebudou odpovídat žádné nastavené hodnotě, tohle určitě upravím.
Ty nuly jsem také spojoval s rušením přenosu. Ještě se na ten tvůj původní kód mrknu, nyní jsem rád, že mi to konečně jede
Ano, máš pravdu, bylo by jistější posílat čísla, která svým součtem nebudou odpovídat žádné nastavené hodnotě, tohle určitě upravím.
Ty nuly jsem také spojoval s rušením přenosu. Ještě se na ten tvůj původní kód mrknu, nyní jsem rád, že mi to konečně jede
Re: Ovládání výstupů - sériová linka
Čau chlapi. Mam prosbu. Řeším podobnej problem a když jsem zkoušel ovládat výstupy (prozatim jsem dal jen kontrolně zpět komunikaci na terminal) zdrojákem co tu zdílel AstroMik tak se mi to opakuje a celkevě to blbne. tento problém řeším cca už skoro 15h a napsal jsem cca 5 druhu zdrojáku jak řešit tento problém, ale všechny dopadjí stejně na ho....
Zdroják jsem použil místní:
a pošlu na to 000001
tak výpis vypadá takhle a nevim proč.
Děkuji za jakoukoliv radu proč nebo nápad jak to vyřešit
Zdroják jsem použil místní:
Kód: Vybrat vše
void setup() {
Serial1.begin(9600);
}
void loop(void)
{
if (Serial1.available()) // kdyz se na seriovem portu objevi nejaka data ...
{
byte hodnota = Serial1.read(); // ... tak je precti do promenne
if ( bitRead(hodnota, 0) == 1) // otestuj nejnizsi bit z prijateho cisla (tlacitko na int_1)
{
Serial1.println("1 zap");// tlacitko na int_1 bylo stisknuto
}
if ( bitRead(hodnota, 1) == 1) // otestuj druhy nejnizsi bit z prijateho cisla (tlacitko na int_2)
{
Serial1.println("2 zap");// tlacitko na int_2 bylo stisknuto
}
if ( bitRead(hodnota, 2) == 1)
{
Serial1.println("3 zap"); // tlacitko na int_3 bylo stisknuto
}
if ( bitRead(hodnota, 3) == 1)
{
Serial1.println("4 zap");// tlacitko na int_4 bylo stisknuto
}
if ( bitRead(hodnota, 4) == 1)
{
Serial1.println("5 zap");// tlacitko na int_5 bylo stisknuto
}
if ( bitRead(hodnota, 5) == 1) // otestuj nejvyssi (6.) bit z prijateho cisla (tlacitko na int_6)
{
Serial1.println("6 zap");// tlacitko na int_6 bylo stisknuto
}
}
}
a pošlu na to 000001
tak výpis vypadá takhle a nevim proč.
Kód: Vybrat vše
01:35:57.527 000001
01:35:58.286 5 zap
01:35:58.295 6 zap
01:35:58.305 5 zap
01:35:58.315 6 zap
01:35:58.315 5 zap
01:35:58.322 6 zap
01:35:58.356 5 zap
01:35:58.356 6 zap
01:35:58.360 5 zap
01:35:58.499 6 zap
01:35:58.500 1 zap
01:35:58.501 5 zap
01:35:58.502 6 zap
01:35:58.502 1 zap
01:35:58.502 3 zap
01:35:58.502 4 zap
01:35:58.502 2 zap
01:35:58.502 4 zap
Re: Ovládání výstupů - sériová linka
Problém je v tom, že když zadáš ve sériovém terminálu text "000001", tak se ve skutečnosti rozloží na 8 bajtů s těmito ASCII kódy:
48
48
48
48
48
49
13 (CR)
10 (LF)
Když se tyhle čísla v programu převedou do binárního tvaru:
0b110000
0b110000
0b110000
0b110000
0b110000
0b110001
0b001101
0b001010
Tak tam, kde vidíš ty "1", tam ti to hlásí "zap"
Ten program, který jsem tu navrhoval, počítá s tím, že přijme jen 1 bajt a ten pak rozloží na bity.
Buď teda můžeš použít nějaký jiný terminál, ve kterém je možné zadávat čísla desítkově (nebo hexadecimálně),
A nebo musíš mít i to vysílací Arduino, které ale neodesílá hodnotu pomocí obvyklé funkce "Serial.print(číslo)", ale použije"Serial.write(číslo)".
Obrázek terminálu po odeslání hexadecimálního čísla 0x01 je tady:
http://astromik.org/forum/serialterm.gif
48
48
48
48
48
49
13 (CR)
10 (LF)
Když se tyhle čísla v programu převedou do binárního tvaru:
0b110000
0b110000
0b110000
0b110000
0b110000
0b110001
0b001101
0b001010
Tak tam, kde vidíš ty "1", tam ti to hlásí "zap"
Ten program, který jsem tu navrhoval, počítá s tím, že přijme jen 1 bajt a ten pak rozloží na bity.
Buď teda můžeš použít nějaký jiný terminál, ve kterém je možné zadávat čísla desítkově (nebo hexadecimálně),
A nebo musíš mít i to vysílací Arduino, které ale neodesílá hodnotu pomocí obvyklé funkce "Serial.print(číslo)", ale použije"Serial.write(číslo)".
Obrázek terminálu po odeslání hexadecimálního čísla 0x01 je tady:
http://astromik.org/forum/serialterm.gif
- pavel1tu
- Příspěvky: 2054
- Registrován: 26 říj 2017, 08:28
- Reputation: 0
- Bydliště: Trutnov
- Kontaktovat uživatele:
Re: Ovládání výstupů - sériová linka
Nechápu, že tu vymýšlíš vymyšlené
Jak píše Astromik, to je ideál, a pokud jde o nějaké přeslechy, dodej tomu "paritní bit" na konec - na wiky jistě najdeš co je paritní bit
osobně mezi stanicemi a centrálkou alarmu posílám 14 informaci (abych měl rezervy), mám to rozložené na 2x8bit(7+parita).
- 0101010 je informace
- 10101010 je informace s paritním bytem
- 10101010 je vlastně 170 v desítkové, což je znak "ª" který pošlu po 485 do centrálky (snad)
-na druhé straně to stejně rozložím i s kontrolou paritního bytu ....
je to dost srozumitelné ? Zatím mi to funguje ....
PS:Další možnost, koupíš si destičku, kde je implementován nějaký protokol, třena CANbus a ten šváb to zajistí za tebe, na strarně příjmu ti vždy vypadne ověřený výsledek - paritu a to další zajistí ten šváb .... jo záleží jaký šváb
Jak píše Astromik, to je ideál, a pokud jde o nějaké přeslechy, dodej tomu "paritní bit" na konec - na wiky jistě najdeš co je paritní bit
osobně mezi stanicemi a centrálkou alarmu posílám 14 informaci (abych měl rezervy), mám to rozložené na 2x8bit(7+parita).
- 0101010 je informace
- 10101010 je informace s paritním bytem
- 10101010 je vlastně 170 v desítkové, což je znak "ª" který pošlu po 485 do centrálky (snad)
-na druhé straně to stejně rozložím i s kontrolou paritního bytu ....
je to dost srozumitelné ? Zatím mi to funguje ....
PS:Další možnost, koupíš si destičku, kde je implementován nějaký protokol, třena CANbus a ten šváb to zajistí za tebe, na strarně příjmu ti vždy vypadne ověřený výsledek - paritu a to další zajistí ten šváb .... jo záleží jaký šváb
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Pavel1TU
"Správně napsaný kod lze číst jako knihu"
Re: Ovládání výstupů - sériová linka
Čau moc děkuji. To mě mohlo také napadnou ) , ale abych se přiznal tak tohle co tu řešíme je ještě závislé na aplikaci co dělá kolega, která posílá textový řetězec v podobě 1.1.1.1.1.1.1.1.1. každých 100ms. A kdysi nám na to fugloval zdroják podobný tomuto:
ale už nemame tu aplikaci a napsala se podobná, která nám ale nefugluje, a proto zkoušíme mnoho podobných variant , ale pořád bez uspěchu.
Mam podezření že zdrojak pro arduino je v pořádku, ale je problém s aplikací. Tedy ještě jednou prosím, zda tam nevidíte nějakou blbost, kterou nevidím . Děkuji
Kód: Vybrat vše
int dopredu;
int dozadu;
int leva;
int prava;
int nahoru;
int dolu;
int magnet;
int svetla;
int klakson;
int blik;
char zahod1;
char zahod2;
void setup() {
Serial1.begin(9600);
pinMode (2, INPUT); // indikace připojení
pinMode(22, OUTPUT); // dopredu
pinMode(24, OUTPUT); //dozadu
pinMode(26, OUTPUT); // leva
pinMode(28, OUTPUT); //prava
pinMode(30, OUTPUT); //nahoru
pinMode(32, OUTPUT); //dolu
pinMode(34, OUTPUT); //magnet
pinMode(36, OUTPUT); //svetla
pinMode(38, OUTPUT); //klakson
pinMode(40, OUTPUT); //blik
}
void loop() {
while (Serial1.available()) {
dopredu = Serial1.parseInt();
dozadu = Serial1.parseInt();
leva = Serial1.parseInt();
prava = Serial1.parseInt();
nahoru = Serial1.parseInt();
dolu = Serial1.parseInt();
magnet = Serial1.parseInt();
svetla = Serial1.parseInt();
klakson = Serial1.parseInt();
if (dopredu > 0) digitalWrite (22, HIGH); else digitalWrite (22, LOW);
if (dozadu > 0) digitalWrite (24, HIGH); else digitalWrite (24, LOW);
if (leva > 0) digitalWrite (26, HIGH); else digitalWrite (26, LOW);
if (prava > 0) digitalWrite (28, HIGH); else digitalWrite (28, LOW);
if (nahoru > 0) digitalWrite (30, HIGH); else digitalWrite (30, LOW);
if (dolu > 0) digitalWrite (32, HIGH); else digitalWrite (32, LOW);
if (magnet > 0) digitalWrite (34, HIGH); else digitalWrite (34, LOW);
if (svetla > 0) digitalWrite (36, HIGH); else digitalWrite (36, LOW);
if (klakson > 0) tone (38, 440, 500);
}
delay(100);
}
Mam podezření že zdrojak pro arduino je v pořádku, ale je problém s aplikací. Tedy ještě jednou prosím, zda tam nevidíte nějakou blbost, kterou nevidím . Děkuji
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 13 hostů