Stránka 1 z 3
Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 17:54
od Axamith
Potřebuji pomocí sériové linky ovládat výstupy Arduina.
Arduino 1, 6 vstupů (log. 0/1)
Po sériové lince posílám šestimístné číslo, 0=vstup vypnutý, 1= vstup zapnutý.
příklad:
000100 (vstup 4 zapnutý, ostatní vypnutý)
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);
pinMode(int_2, INPUT);
pinMode(int_3, INPUT);
pinMode(int_4, INPUT);
pinMode(int_5, INPUT);
pinMode(int_6, INPUT);
}
void loop() {
// Serial.print("vypis ovladani: ");
//vstup 1
if(digitalRead(int_1)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
//vstup 2
if(digitalRead(int_2)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
//vstup 3
if(digitalRead(int_3)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
//vstup 4
if(digitalRead(int_4)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
//vstup 5
if(digitalRead(int_5)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
//vstup 6
if(digitalRead(int_6)== HIGH){
Serial.print("0");
}
else{
Serial.print("1");
}// end
Nevím si rady s příjmem dat po sériové lince, respektive rozložení tohoto šestimístného čísla na jednotlivé číslice a přiřazení k jednotlivým proměnným, se kterými bych dále pracoval (podmínky, ovládání výstupního pinu, sepnutí konkrétního relé).
Nakopne mě někdo správným směrem? Možná jsem nevhodně postavil už základ komunikace, to šestimístné číslo.
Re: Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 19:31
od Wojta
Já bych posílal jen byte. Máš tam o 2 bity víc než potřebuješ ale to neva, bude jednodušší to z něj dostat.
Pak už můžeš jen použít funkci bitRead(x,y)
Ta ti vrátí hodnotu bitu na pozici y v čísle x. Popřípadě můžeš použít obyčejnou logiku a bity maskovat.
Reference na bitRead()
https://www.arduino.cc/reference/en/lan ... s/bitread/
Re: Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 19:33
od SkullKeep
Nebo posílat to číslo né binárně 000100, ale jako součet pozice v dvojkové soustavě jako 4. A ostatní kanály se přepočítají z toho čísla.
Re: Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 20:23
od Axamith
Posílání pozice jedničky je dobrý nápad. Vyzkouším to. Situace dvou jedniček v řadě nenastane, takže je to jen o matematice. Uvidíme, co z toho vyleze.
Re: Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 20:28
od AstroMiK
Kdyby bylo možné trochu zpřeházet ty vstupní piny (na D2 až D7), tak by se to dalo ještě jednoduššeji
přímým přístupem přes vnitřní registry ATmega328:
Kód: Vybrat vše
void setup(void)
{
DDRD &= 0b00000011; // piny D7 az D2 na vstup, piny D0 a D1 nechat beze zmeny (Rx,Tx)
PORTD |= 0b11111100; // na D7 az D2 pripojit pripadne i vnitrni Pull-Upy (D0 a D1 beze zmeny)
Serial.begin(9600);
}
void loop(void)
{
byte hodnota = (PIND & 0b11111100); // osekat ty komunikacni piny D0 a D1
Serial.println (hodnota);
delay(1000);
}
Re: Ovládání výstupů - sériová linka
Napsal: 28 pro 2017, 21:28
od AstroMiK
Ještě doplnění k mému předchozímu příspěvku:
Pro "kopírování" stavů pinů D2 až D7 z "Arduina 1" na "Arduino 2" pomocí komunikace by šlo použít tyhle 2 programy.
Propojení :
Tx -> Rx
Rx -> Tx
GND -> GND
Vcc -> Vcc
Odesílání dat (čtení pinů) - Arduino 1
Kód: Vybrat vše
void setup(void)
{
DDRD &= 0b00000011; // piny D7 az D2 na vstup, piny D0 a D1 nechat beze zmeny (Tx,Rx)
PORTD |= 0b11111100; // na D7 az D2 pripojit pripadne i Pull-Upy
Serial.begin(9600);
}
void loop(void)
{
byte hodnota = (PIND & 0b11111100); // osekat ty komunikacni piny D0 a D1
Serial.write (hodnota);
delay(200);
}
Příjem dat (ovládání pinů) - Arduino 2
Kód: Vybrat vše
void setup(void)
{
DDRD |= 0b11111100; // piny D7 az D2 na vystup, piny D0 a D1 nechat beze zmeny (Tx,Rx)
Serial.begin(9600);
}
void loop(void)
{
if (Serial.available()) // kdyz se na seriovem portu objevi nejaka data ...
{
byte hodnota = Serial.read(); // ... tak je precti do promenne
hodnota = hodnota | (PORTD & 0b00000011); // Pridej k tomu aktualni stav komunikacnich pinu
PORTD = hodnota; // A cely vysledek zapis najednou do PORTD
}
}
Re: Ovládání výstupů - sériová linka
Napsal: 29 pro 2017, 08:49
od Axamith
Bohužel, piny jsou pevně dané. Mám už udělaný a osazený plošňák
Re: Ovládání výstupů - sériová linka
Napsal: 29 pro 2017, 10:00
od Axamith
Abych ještě upřesnil, o co jde. Řeším ovládání ventilů závlahy, částečně jsem již řešil
https://arduino.cz/forum/tema/dalkove-ovladani-ventilu/
https://www.arduino-forum.cz/viewtopic.php?f=19&t=45
Výstupy (6x) z programovací jednotky (24V~) usměrním, stabilizuji, proženu převodníkem úrovní na vstupy Arduina, výsledné šesti číslo (nebo cokoliv jiného) pošlu po sériové lince k Arduinu u ventilů a podle výsledku spínám relé ovládající jednotlivé ventily.
HW to mám hotové, teď řeším přenos informace po sériové lince o sepnutém vstupu na relé.
- blokove_schema.png (2.83 KiB) Zobrazeno 5126 x
Re: Ovládání výstupů - sériová linka
Napsal: 29 pro 2017, 10:33
od AstroMiK
... tak v tom případě bych to viděl nějak takhle:
Vysílací Arduino:
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 = 0;
// 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 += 4;
if(digitalRead(int_4)== LOW) vysilana_hodnota += 8;
if(digitalRead(int_5)== LOW) vysilana_hodnota += 16;
if(digitalRead(int_6)== LOW) vysilana_hodnota += 32;
Serial.write(vysilana_hodnota);
delay(200); // dostatecne dlouha doba, aby prijimaci Arduino melo cas prijata data zpracovat a nezahltil se mu prijimaci buffer
}
A přijímací Arduino (v podmínkách pak místo komentářů doplnit příslušné akce):
Kód: Vybrat vše
void setup(void)
{
Serial.begin(9600);
}
void loop(void)
{
if (Serial.available()) // kdyz se na seriovem portu objevi nejaka data ...
{
byte hodnota = Serial.read(); // ... tak je precti do promenne
if ( bitRead(hodnota,0) == 1) // otestuj nejnizsi bit z prijateho cisla (tlacitko na int_1)
{
// tlacitko na int_1 bylo stisknuto
}
if ( bitRead(hodnota,1) == 1) // otestuj druhy nejnizsi bit z prijateho cisla (tlacitko na int_2)
{
// tlacitko na int_2 bylo stisknuto
}
if ( bitRead(hodnota,2) == 1)
{
// tlacitko na int_3 bylo stisknuto
}
if ( bitRead(hodnota,3) == 1)
{
// tlacitko na int_4 bylo stisknuto
}
if ( bitRead(hodnota,4) == 1)
{
// tlacitko na int_5 bylo stisknuto
}
if ( bitRead(hodnota,5) == 1) // otestuj nejvyssi (6.) bit z prijateho cisla (tlacitko na int_6)
{
// tlacitko na int_6 bylo stisknuto
}
}
}
Re: Ovládání výstupů - sériová linka
Napsal: 29 pro 2017, 11:21
od AstroMiK
Ještě jsem koukal na ten tvůj plošňák a nejsem si jistý, jestli nebude vadit, že nemáš spojené GND mezi vysílacím a přijímacím Arduinem.
Na jednosměrnou komunikaci by měl stačit jen jeden drát. Vysílací Arduino by mělo zapojené Tx a přijímací Rx.
Ale myslím, že musí být nějak vzájemně definované to GND.