Projekt Testování I2C adresy

Protože někdy potřebuji ověřit I2C adresu připojovaného zařízení (třeba podle návodu nastavená adresa nefunguje) musel jsem vyhrabat volné arduino, propojit s testovaným zařízením, nahrát program a na počítači provést kontrolu. Dospěl jsem k závěru, že se mi bude hodit krabička, která bude mít vše v jednom.

Pomocí přepínačů nastavím na konektoru pořadí napájecích zdířek (VCC/GND, nebo GND/VCC) a totéž provedu s vodiči I2C (SDA/ SCL, NEBO SCL/SDA). Vzhledem k tomu, že jsou tyto vodiče obvykle vedle sebe, ale v různém pořadí, můžu nastavit libovolnou kombinaci. Protože se používají dvě různá napětí, vytvořil jsem dvě větve. Pro 5V a 3V3. Pokud mám vše nastavené a testované zařízení je vloženo do konektoru (pokud to vlastnosti dovolí) nebo připojené propojovacím kabelem, připojím konektor USB-C do napájecí zdířky (stačí nabíječka k telefonu). Pokud se připojí konektor kabelem k zapojení které má své napájení, nesmí se napájecí konektor použít – propojily by se dva zdroje paralelně.
Naskočí úvodní obrazovka:

Poznámka: obrazovky s chybou jsou předpoklad. Nemůžu ověřit. Nápis „Chyba“ mi naskočil jedou díky chybě v propojení.

V základu je zařízení určeno pro zjištění jedné adresy. Přesto ukáže i více adres. V pravém sloupci je postupně vypíše. Maximum vypsaných adres je prvních 9. Víc jsem nepotřeboval řešit, protože to není prioritní úkol této krabičky.
Displej lze použít každý, který není připojen přes sběrnici I2C, protože program nepozná 2 stejné adresy.
Program je přizpůsobený z návodu DRÁTEK.

Schéma:

 

Pod pokličkou:

 

Ukázka výsledku:

 

Program pro Arduino:

//zapojení pinů obrazovky:
//             CS  DC/RS  RESET  SDI/MOSI  SDO/MISO  SCK  LED    VCC     GND
//Arduino Uno  A1   A3     A2      11        12      13   A0   5V/3.3V   GND
//            T_IRQ  T_DO  T_DIN  T_CS  T_CLK
//Arduino Uno  6      4      5     2      3

//Remember to set the pins to suit your display module!
// Piny lze po změně v programu libovolně změnit kromě pinů 11, 12 a 13.
// Pin pro LED ačkoliv se nepoužije, musí být definován.
// Přestože je displej uveden i pro napětí 5V, používám ho na 3V3.

/*********************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, QD electronic SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
**********************************************************************************/

// knihovna pro komunikaci I2C sběrnice
#include <Wire.h>
// nastavení čísel propojovacích pinů

#define I2C_SDA A4
#define I2C_SCL A5

// knihovny pro obrazovku
#include <LCDWIKI_GUI.h>    //Core graphics library
#include <LCDWIKI_SPI.h>    //Hardware-specific library
#include <LCDWIKI_TOUCH.h>  //touch screen library

// definice parametrů displeje
#define MODEL ILI9341
#define CS A1
#define CD A3
#define RST A2
#define LED A0  // Pokud není použita regulace jasu podsvícení, připojit na 3V3.

// definování parametrů dotyku obrazovky
#define TCS 2
#define TCLK 3
#define TDOUT 4
#define TDIN 5
#define TIRQ 6

// definice hardwarového spi režimu takto:
// pokud je model IC znám nebo moduly jsou nečitelné, můžete použít tuto vytvořenou funkci
LCDWIKI_SPI my_lcd(MODEL, CS, CD, RST, LED);  // model,cs,dc,reset,led
// pokud není model IC znám a moduly jsou čitelné, můžete použít tuto vytvořenou funkci
//LCDWIKI_SPI my_lcd(240,320,CS,CD,RST,LED); //model,cs,dc,reset,led

// definice dotykového režimu je následující:
LCDWIKI_TOUCH my_touch(TCS, TCLK, TDOUT, TDIN, TIRQ);  // tcs,tclk,tdout,tdin,tirq

// definice barev
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

// vytvoření pomocných proměnných
byte chyba, adresa;
int pocetZarizeni = 0;
byte bodY = 37;

void setup(void) {
  // zahájení komunikace po I2C sběrnici,
  Wire.begin();

  // inicializace displeje
  my_lcd.Init_LCD();
  my_lcd.Set_Rotation(3);
  my_touch.TP_Set_Rotation(2);
  my_touch.TP_Init(my_lcd.Get_Rotation(), my_lcd.Get_Display_Width(), my_lcd.Get_Display_Height());
  // nastavení černé obrazovky
  my_lcd.Fill_Screen(BLACK);
  // nastavení černé barvy na pozadí textu. Jiná barva není použita, proto ji nastavuji zde
  my_lcd.Set_Text_Back_colour(BLACK);
  // vyobrazí úvodní obrazoku
  menu();
}

void loop() {
  // natočení dotykové vrstvy
  // v tomto případě pouze je důležítá oriantace svisle / vodorvně, protože se používá celá plocha
  my_touch.TP_Scan(0);

  // skenování dotyku a vyhodnocení co má nastat
  if (my_touch.TP_Get_State() & TP_PRES_DOWN) {
    pocetZarizeni = 0;  // vynulování počítadla zařízení
    my_lcd.Set_Text_Size(2);
    my_lcd.Set_Text_colour(CYAN);
    my_lcd.Print_String("     ", 250, 215);  // odstraní nápis "KONEC" z obrazovky
    my_lcd.Print_String("   ", 190, 215);    // vymaže počet zařízení z obrazovky
    for (bodY = 37; bodY < 200; bodY = bodY + 19) {
      my_lcd.Print_String("   ", 274, bodY);  // vymaže adresy z obrazovky z předchozího hledání
    }
    bodY = 37;
    my_lcd.Print_Number_Int(pocetZarizeni, 190, 215, 1, " ", 10);
    my_lcd.Set_Text_Size(3);
    my_lcd.Set_Text_colour(MAGENTA);
    my_lcd.Print_String("  Skenuji...   ", 1, 130);
    // pauza aby se na okamžik zobrazil nápis Skenuji
    delay(500);
    // smyčka pro hledání zařízení
    // I2C zařízení mohou mít adresu 1-126
    for (adresa = 1; adresa < 127; adresa++) {
      // zahájení komunikace a jeho následné ukončení,
      // při ukončení probíhá detekce zařízení pomocí
      // kontroly návratové hodnoty
      Wire.beginTransmission(adresa);
      chyba = Wire.endTransmission();
      // pokud nám zařízení odpoví '0',
      // tak funguje správně
      if (chyba == 0) {
        // vytištění informací o zařízení včetně
        // jeho adresy v hexa formátu
        my_lcd.Set_Text_colour(GREEN);
        if (pocetZarizeni == 0) {
          my_lcd.Print_String(" I2C je: 0x", 1, 130);
        }
        my_lcd.Print_Number_Int(adresa, 199, 130, 1, " ", 10);
        // přepíše / vymaže případné znaky z předchozího textu
        if (adresa > 99) {
          my_lcd.Print_String(" ", 253, 130);
        } else {
          my_lcd.Print_String("  ", 235, 130);
        }
        // inkrementace počítadla zařízení
        pocetZarizeni++;
        // vypsání adresy do sloupce na pravé straně obrazovky pro případ že je zařízení víc
        my_lcd.Set_Text_Size(2);
        my_lcd.Print_Number_Int(pocetZarizeni, 190, 215, 1, " ", 10);
        if (bodY < 200) {
          my_lcd.Set_Text_colour(YELLOW);
          my_lcd.Print_Number_Int(adresa, 274, bodY, 1, " ", 10);
          bodY = bodY + 19;
        }
        my_lcd.Set_Text_Size(3);
      }
      // při chybě v komunikaci je chybný výstup 4
      else if (chyba == 4) {
        my_lcd.Set_Text_colour(RED);
        // vytištění informací o zařízení včetně
        // jeho adresy v hexa formátu
        my_lcd.Print_String(" Chyba : 0x", 1, 130);
        my_lcd.Print_Number_Int(adresa, 211, 130, 1, " ", 10);
        if (adresa > 99) {
          my_lcd.Print_String(" ", 253, 130);
        } else {
          my_lcd.Print_String("  ", 235, 130);
        }
        if (bodY < 200) {
          my_lcd.Set_Text_colour(RED);
          my_lcd.Print_Number_Int(adresa, 274, bodY, 1, " ", 10);
          bodY = bodY + 19;
        }
      }
    }
    // kontrola počítadla zařízení
    if (pocetZarizeni == 0) {
      my_lcd.Set_Text_colour(YELLOW);
      // nebylo nalezeno žádné zařízení, protože neproběhla inkrementace
      my_lcd.Print_String("I2C nenalezeno.", 1, 130);
    }
    my_lcd.Set_Text_Size(2);
    my_lcd.Set_Text_colour(YELLOW);
    my_lcd.Print_String("KONEC", 250, 215);
  }
  delay(250);  // pauza před dalším spuštěním smyčky
}

void menu(void) {

  // záhlaví / logo
  my_lcd.Set_Text_Mode(boolean(1));  // vypne barvu pozadí textu (rychlejší zobrazení taxtu)
  my_lcd.Set_Draw_color(YELLOW);     // nastaví barvu grafických obrazců
  my_lcd.Fill_Circle(15, 15, 15);    // plný kruh
  my_lcd.Set_Draw_color(BLUE);
  my_lcd.Fill_Circle(15, 15, 13);

  my_lcd.Set_Draw_color(YELLOW);
  my_lcd.Fill_Rectangle(19, 8, 20, 21);  // plný obdélník
  my_lcd.Fill_Rectangle(14, 14, 18, 15);
  my_lcd.Fill_Rectangle(12, 8, 13, 18);
  my_lcd.Draw_Line(11, 19, 12, 19);  // čára
  my_lcd.Fill_Rectangle(6, 17, 7, 18);
  my_lcd.Draw_Line(7, 19, 8, 19);
  my_lcd.Draw_Line(7, 20, 12, 20);
  my_lcd.Draw_Line(8, 21, 11, 21);

  my_lcd.Fill_Rectangle(19, 0, 319, 1);
  my_lcd.Fill_Rectangle(318, 2, 319, 28);
  my_lcd.Fill_Rectangle(19, 29, 319, 30);

  my_lcd.Set_Text_Size(2);                            // nastaví velikost textu
  my_lcd.Set_Text_colour(CYAN);                       // nastaví barvu textu
  my_lcd.Print_String("Zjisteni I2C adresy", 60, 8);  // vypíše text, začátek na souřadnicích x, y

  my_lcd.Set_Draw_color(CYAN);
  my_lcd.Draw_Line(98, 7, 99, 7);  // tyto čáry vykreslují diakritiku
  my_lcd.Draw_Line(103, 7, 104, 7);
  my_lcd.Draw_Line(99, 8, 103, 8);
  my_lcd.Draw_Line(100, 9, 102, 9);

  my_lcd.Draw_Line(122, 7, 123, 7);
  my_lcd.Draw_Line(127, 7, 128, 7);
  my_lcd.Draw_Line(123, 8, 127, 8);
  my_lcd.Draw_Line(124, 9, 126, 9);

  my_lcd.Draw_Line(149, 7, 150, 7);

  my_lcd.Set_Text_colour(WHITE);
  my_lcd.Print_String("Stisk obrazovky", 70, 40);
  my_lcd.Print_String("spusti hledani.", 70, 65);
  my_lcd.Set_Draw_color(WHITE);
  my_lcd.Draw_Line(135, 64, 136, 64);

  my_lcd.Draw_Line(207, 64, 208, 64);
  my_lcd.Draw_Line(206, 65, 207, 65);
  my_lcd.Draw_Line(206, 66, 207, 66);

  my_lcd.Draw_Line(231, 64, 232, 64);

  my_lcd.Set_Text_Size(3);
  my_lcd.Set_Text_colour(CYAN);
  my_lcd.Print_String(" Pripraveno... ", 1, 130);
  my_lcd.Set_Draw_color(CYAN);
  my_lcd.Draw_Line(40, 130, 42, 130);
  my_lcd.Draw_Line(47, 130, 49, 130);
  my_lcd.Draw_Line(41, 131, 43, 131);
  my_lcd.Draw_Line(46, 131, 48, 131);
  my_lcd.Draw_Line(42, 132, 47, 132);
  my_lcd.Draw_Line(43, 133, 46, 133);

  my_lcd.Set_Text_Size(2);
  my_lcd.Set_Text_colour(CYAN);
  my_lcd.Print_String("Pocet zarizeni:", 10, 215);
  my_lcd.Print_Number_Int(pocetZarizeni, 190, 215, 1, " ", 10);

  my_lcd.Draw_Line(36, 214, 37, 214);
  my_lcd.Draw_Line(41, 214, 42, 214);
  my_lcd.Draw_Line(37, 215, 41, 215);
  my_lcd.Draw_Line(38, 216, 40, 216);

  my_lcd.Draw_Line(108, 214, 109, 214);
  my_lcd.Draw_Line(113, 214, 114, 214);
  my_lcd.Draw_Line(109, 215, 113, 215);
  my_lcd.Draw_Line(110, 216, 112, 216);

  my_lcd.Draw_Line(123, 214, 124, 214);

  my_lcd.Draw_Line(171, 214, 172, 214);

  my_lcd.Set_Text_Size(2);
  my_lcd.Set_Text_colour(YELLOW);
  my_lcd.Print_String("KONEC", 250, 215);
  my_lcd.Set_Text_Mode(boolean(0));  // zapne barvu pozadí - při psaní textu v místě, kde již text je, by jinak nedošlo k úplnému odstranění předchozího znaku
}

Použité komponenty:

Další podobné články

Řízení rychlosti krokového motoru potenciometrem

Cílem projektu je navrhnout a sestavit obvod s krokovým motorem, který umožní řízení jeho rychlosti pomocí potenciometru. Tato technologie bude využitelná například při výrobě filamentu z PET lahví pro 3D tisk. Projekt zahrnuje výběr vhodného motoru, ovladače, potenciometru a mikrokontroléru, které budou propojeny a naprogramovány pro optimální funkci.