keskiviikko 1. maaliskuuta 2017

SarjaLiikenne I

Jokainen kerta kun ohjelma ladataan työkalusta Arduinolle, on käytössä sarjaliikenne. Bitit siis kulkevat ajallisesti peräkkäin. Vastaanottavan pään täytyy siis tietää, missä muodossa dataa syötetään ja millä nopeudella. Niin sanottuja protokollia eli määreitä siitä, missä muodossa sanoma annetaan, on useita, mutta ei tällä kerralla siitä tämän enempää. Tärkeintä on joka tapauksessa, että siirtonopeus on sama molemmissa päissä. Muu on normaalisti sovittu perusasetuksissa.
     Arduinolta saadaan myös tuloksia ohjelman pyöriessä. Tämä on ensiarvoisen oleellista virheiden debukkauksessa eli korjaamisessa. Aina tahtoo tulla yllätyksiä raakaversioiden toiminnassa, sillä aivan kaikkea ei ole helppo miettiä ja ohjelmoida etukäteen. Vähän väliä joutuu pohtimaan (ainakin minä joudun), mikä taas meni pieleen!
     Ohjelman lataamisen ja tulosten ruudulle printtaamisen lisäksi voidaan työkalusta syöttää dataa Arduinolle myös ohjelman jo pyöriessä. Serial Monitor-näytön yläosassa on vaakasuora palkki, mihin voidaan kirjoittaa ja lähettää dataa Arduinolle. Viesti lähtee joko painamalla ENTteriä tai klikkaamalla Send-painiketta. Tässä tulee huomioida, että mikrokontrolleri ottaa vastaan yhden merkin kerrallaan (kuvassa on numerot 0 .. 9, mutta nekin siirtyvät merkki kerrallaan). Jos halutaan lähettää pidempi rimpsu (esim. satakaksikymmentäkolme, 123), on se kerättävä merkki merkiltä talteen taulukoksi ja käsiteltävä ohjelmallisesti sen jälkeen. Toinen huomioitava seikka on, että työkaluohjelma lähettää ASCII-merkkejä, joten ne on tulkittava (tässä esimerkissä numeroiksi: (isDigit(Chr_Merkki).

Tässä esimerkissä (ja kuvissa) lähetän numerot 0 .. 9, joten ne tulostuvat 7-segmenttinäyttöön peräkkäin (viive välissä) ja näyttöruutuun alekkain. Kirjoitus IC-piirille, sarjassa sisään / rinnan ulos (74CHT595). Piirilevy on sama, mikä oli aiemmin käytössä ”nopassa” ja ”koodilukossa”.
     Ohjelmassa 7-segmenttinäytön ohjaukset ovat melko suoria kopioita noista edellä mainitsemieni sovellusten aliohjelmista. Digitaliliitynnät on tehty yleisellä tasolla ja pinnien toiminta määritelty asetuksissa. Pääohjelmassa odotetaan, että sarjaporttiin ilmestyy dataa (if(Serial.available()){). Kun merkki ilmestyy, ja se on numero, sijoitetaan se int-muuttujaan. (Int_Numero). Koska tuleva data on tässä ASCII-merkki, vähennetään merkitä ASCII-nolla (ASCII 48DEC .. '0'). jolloin saadaan numerot 0 .. 9. Numero lähetetään 7-segmentti aliohjelmille ja viiveen (0,5s) jälkeen myös ruudulle. Koska numero tulostetaan ruudulle (Serial.println(Int_Numero);) komennolla, tulee jokaisen numeron jälkeen rivinvaihto (LF ja CR), joten ruudulle numerot tulostuvat päällekäin. Merkit tulostuvat ruudulle yksi kerrallaan, eikä yhtenä pötkönä, miltä ne näyttävät ruudulla olevan. Pääohjelman lopussa ”pimennetään” 7-segmenttinäyttö. 

video


OHJELMA 39
/***************************************
     *  Ohjelma 39
     *  28.02.2017
     *  Näyttö ruudulle ja 7-segmenttiin
     **************************************/

    // MÄÄRITTELYT:
         int Int_Numero = 0;
         char Chr_Merkki = " ";
         boolean Arr_Data[8] = {0,0,0,0,0,0,0,0};// Näyttö
   
   // Sarjadatan syöttö 74HCT595
         const int Con_DS_Data = 6;          // Sarjadatan syöttö
         const int Con_SHCP_Kello = 7;    // Sarjadatan kellotus
         const int Con_STCP_Siirto = 8;    // Syöttö rinnanlähtöön

   // ALIOHJELMAT
   // 7-segmenttinäytön tyhjennys
      void Fun_Tyhjenna(){
        for(int i = 0; i < 8; i++){
          digitalWrite(Con_DS_Data, 0);
          digitalWrite(Con_SHCP_Kello, HIGH);
          digitalWrite(Con_SHCP_Kello, LOW);
          digitalWrite(Con_STCP_Siirto, HIGH);
          digitalWrite(Con_STCP_Siirto, LOW);}
       }// Tyhjennyksen loppu

   // 7-segmenttinäytön lataus aliohjelma
   // N7seg_Aliohjelma_v1 N7seg_ALI_v1.N1Maa17
         void Fun_N7seg(int numero){
            int Seq_7nayt = numero + 1;
   // 7-segmenttinäytön numerot
          boolean Arr_Data0[8] = {1,0,1,1,1,1,1,0}; // 0
          boolean Arr_Data1[8] = {0,0,0,0,1,1,0,0}; // 1
          boolean Arr_Data2[8] = {0,1,1,1,0,1,1,0}; // 2
          boolean Arr_Data3[8] = {0,1,0,1,1,1,1,0}; // 3
          boolean Arr_Data4[8] = {1,1,0,0,1,1,0,0}; // 4
          boolean Arr_Data5[8] = {1,1,0,1,1,0,1,0}; // 5
          boolean Arr_Data6[8] = {1,1,1,1,1,0,1,0}; // 6
          boolean Arr_Data7[8] = {0,0,0,0,1,1,1,0}; // 7
          boolean Arr_Data8[8] = {1,1,1,1,1,1,1,0}; // 8
          boolean Arr_Data9[8] = {1,1,0,1,1,1,1,0}; // 9

         switch (Seq_7nayt) {
             case 1: for(int i = 0; i < 8; i++){
                Arr_Data[i] = Arr_Data0[i];}break;
            case 2: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data1[i];}break;
            case 3: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data2[i];}break;
            case 4: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data3[i];}break;
            case 5: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data4[i];}break;
            case 6: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data5[i];}break;
            case 7: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data6[i];}break;
            case 8: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data7[i];}break;
            case 9: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data8[i];}break;
            case 10: for(int i = 0; i < 8; i++){
               Arr_Data[i] = Arr_Data9[i];}break;
        }// Bittijonojen lataus loppu
    }// Näytön latauksen aliohjelman loppu

   // Numeroiden syöttö 7-segmenttinäyttöön
        void Fun_Naytto(int j){
          Fun_Tyhjenna();
          Fun_N7seg(j);
             for(int i = 0; i < 8; i++){
                digitalWrite(Con_DS_Data, Arr_Data[i]);
                digitalWrite(Con_SHCP_Kello, HIGH);
                digitalWrite(Con_SHCP_Kello, LOW);
             }// Sarjakirjoitus loppu
   // Sarjadatan siirto lähtöihin
            digitalWrite(Con_STCP_Siirto, HIGH);
            digitalWrite(Con_STCP_Siirto, LOW);
   }// Näytön loppu

// ASETUKSET:
   void setup(){                 
      Serial.begin(9600);         
        pinMode(Con_DS_Data, OUTPUT);
        pinMode(Con_SHCP_Kello, OUTPUT);
        pinMode(Con_STCP_Siirto, OUTPUT);
  }// Asetuksen loppu

 // PÄÄLOOPPI                  
      void loop(){
          if(Serial.available()){
             Chr_Merkki = Serial.read();
               if(isDigit(Chr_Merkki)){
                  Int_Numero = Chr_Merkki - '0';
                  Fun_Naytto(Int_Numero); // Tulostus 7-segmenttiin
                  delay(500);     
          }// if numeron tunnistus loppu
  // Tulostus työkalun ruudulle
           Serial.print("Tuli numero :");  Serial.println(Int_Numero);
       }// if sarjadatan tunnistuksen loppu
         Fun_Tyhjenna();  //Jos ei dataa, näyttö pimeänä

        delay(1);
    } // Pääohjelma LOPPU

Ei kommentteja:

Lähetä kommentti