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

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.