Ovládání výstupů - sériová linka

Axamith
Příspěvky: 530
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Ovládání výstupů - sériová linka

Příspěvek od Axamith » 28 pro 2017, 17:54

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.

Wojta
Příspěvky: 184
Registrován: 22 črc 2017, 16:39
Reputation: 0

Re: Ovládání výstupů - sériová linka

Příspěvek od Wojta » 28 pro 2017, 19:31

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/

Uživatelský avatar
SkullKeep
Příspěvky: 290
Registrován: 23 srp 2017, 18:51
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Ovládání výstupů - sériová linka

Příspěvek od SkullKeep » 28 pro 2017, 19:33

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.
:twisted: :?: :arrow: :geek: P. Q. M.

Axamith
Příspěvky: 530
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Ovládání výstupů - sériová linka

Příspěvek od Axamith » 28 pro 2017, 20:23

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.

AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Ovládání výstupů - sériová linka

Příspěvek od AstroMiK » 28 pro 2017, 20:28

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);
  }



AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Ovládání výstupů - sériová linka

Příspěvek od AstroMiK » 28 pro 2017, 21:28

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
      }
  }
 
 

Axamith
Příspěvky: 530
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Ovládání výstupů - sériová linka

Příspěvek od Axamith » 29 pro 2017, 08:49

Bohužel, piny jsou pevně dané. Mám už udělaný a osazený plošňák :-(

Axamith
Příspěvky: 530
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Ovládání výstupů - sériová linka

Příspěvek od Axamith » 29 pro 2017, 10:00

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
blokove_schema.png (2.83 KiB) Zobrazeno 5041 x
PCB_1.png
PCB_2.png

AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Ovládání výstupů - sériová linka

Příspěvek od AstroMiK » 29 pro 2017, 10:33

... 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 
           }
      }
  }


AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Ovládání výstupů - sériová linka

Příspěvek od AstroMiK » 29 pro 2017, 11:21

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.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 11 hostů