Budowa nowych, nawet bardzo złożonych funkcjonalnie, układów elektronicznych może być bardzo prosta i przyjemna. Pod warunkiem, że twórczo wykorzystamy to co jest dostępne na rynku w formie gotowych modułów. A jest tego sporo dzięki pracowitym Chińczykom i w śmiesznie niskich cenach. Sercem takiego projektu musi być oczywiście jakiś mikrokontroler ale z tym jest najmniejszy kłopot od czasu pojawienia się ARDUINO. Wszystkie te elementy trzeba jednak jakoś inteligentnie z sobą połączyć. Dziś o tym jak to zrobić bez zbytniego wysiłku...
Patrząc na każdy mikroprocesor widzimy porty, porty i jeszcze raz porty. Większość z nich to jednobitowe piny cyfrowe lub piny analogowe. I to w zasadzie cała elektronika. We wszystkich układach mamy albo dwustanowy sygnał binarny albo liniowy sygnał analogowy. Ale o ile sygnał analogowy niesie ze sobą informacje związaną jedynie z jego wartością to możliwości sygnałów cyfrowych okazały się dużo większe. Paradoksalnie. Mając jedynie dwa stany do przekazania większej ilości informacji musiał pojawić się dodatkowy element - czas. I tak narodził się protokół czyli uporządkowana zmiana sygnału binarnego w czasie.
I choć dzisiaj w mikrokontrolerach wciąż przeważają porty cyfrowe lub analogowe, do których można podłączyć proste sygnały, to dominującą funkcją stanowiącą o sile rynkowej danego układu staje się umiejętność obsłużenia jak największej liczby protokołów komunikacyjnych. Znakomitym przykładem jest tu historia ESP8266. Procesor jakich tysiące innych zagarnął potężną część rynku tylko jednym - ma sprzętowo zaimplementowany protokół WiFi w nieprzyzwoicie niskiej cenie .
Dziś patrząc poważnie na mikrokontroler powinniśmy widzieć nie ilość dostępnych portów cyfrowych czy analogowych a ilość i rodzaj sprzętowo obsługiwanych protokołów komunikacyjnych.
Standardowo większość procesorów dla amatorskiej elektroniki obsługuje następujące ich rodzaje:
- I2C - wolny protokół komunikacyjnych krótkiego zasięgu danych cyfrowych
- I2S - cyfrowy protokół danych analogowych (audio)
- SPI - szybszy (od I2C) protokół komunikacyjny
- UART - 5V lub 3V3 odpowiednik protokołu RS232
Lepsze modele procesorów dla hobbystów posiadają dodatkowo
- WiFi 802.11 - (w ESP to standard) protokół komunikacji radiowej
- Bluetooth - protokół komunikacji radiowej krótkiego zasięgu
- Ethernet - komunikacja przewodowa LAN
- SDIO - protokół dla kart pamięci (dawniej SD)
- IR - komunikacja w podczerwieni
Wire.begin();
Wire.begin( x , y );
gdzie x to port linii SDA a y linii SCL
W procesorach posiadających więcej niż jeden I2C (ESP32) jednoczesne korzystanie z obu kanałów transmisji wymaga innej deklaracji portów
Jak widać w powyższych przykładach nie ma tu żadnej informacji jak ustawić adres urządzenia abonenckiego podłączonego do szyny I2C. Taką informację zawierać będzie biblioteka dla danego modułu.
Ale możemy ją również uzyskać skanując porty procesora pod kątem przyłączonych do niego modułów I2C. Szkic takiego skanera można ściągnąć tu
#include <Wire.h>
uint8_t i2cPins[][2] = {
{D2, D1}, // Standardowe piny I2C
{D5, D6}
};
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
scanAll();
delay(1000);
}
void scanAll()
{
for (int x = 0; x < sizeof(i2cPins) / (sizeof(uint8_t) * 2); x++) {
Serial.print("I2C na pinach SDA: ");
Serial.print(i2cPins[x][0]);
Serial.print(",SCL: ");
Serial.println(i2cPins[x][1]);
Wire.begin(i2cPins[x][0], i2cPins[x][1]);
scan();
}
}
void scan()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for (address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address < 16)
Serial.print("0");
Serial.print(address, HEX);
Serial.println(" !");
nDevices++;
}
else if (error == 4)
{
Serial.print("Unknown error at address 0x");
if (address < 16)
Serial.print("0");
Serial.println(address, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
}
Co zrobić z tą wiedzą podpowie nam nie za długo nasz ulubiony ciąg dalszy.
Brak komentarzy:
Prześlij komentarz