#include #include #include #include #define SD_CHIP_SELECT_PIN 4 #define ETHERNET_CHIP_SELECT_PIN 10 // Массив-изображение: 1 байт (8 бит) -- одна строка из 8 // светодиодов char iconBytes[8]; // IP-адрес (укажите тот, который свободен в вашей сети) IPAddress ip(192, 168, 10, 141); // MAC-адрес указан на наклейке, на обороте платы byte mac[] = { 0x5E, 0xBD, 0x3E, 0xEF, 0xFE, 0xBD }; // Домен сервера, на который мы будем обращаться const char server[] = "api.openweathermap.org"; // Маска, по которой мы ищем название иконки const char token[] = "icon=\"???"; // Сюда будет сохраняться номер иконки из ответа API char imageId[12] = "no"; // Объект для работы с enthernet-сетью EthernetClient client; // Номера пинов и размер рабочего поля в индикаторе #define N_X 1 #define N_Y 1 #define DATA_PIN 5 #define CLK_PIN 6 #define LATCH_PIN 2 // Объект для работы с матрицей rgb_matrix marix = rgb_matrix(N_X, N_Y, DATA_PIN, CLK_PIN, LATCH_PIN); // Время последнего обновления unsigned long startTime = 0; void readIconName() { // Соединяемся с серером if (client.connect(server, 80)) { // И посылаем запрос с тем, что хотим получить страницу // на определенном адресе client.println("GET /data/2.5/weather?q=Moscow&mode=xml&units=metric HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); // Ждем, пока придет ответ while (!client.available()) ; char symbol; int i = 0, j = 0; // Пока есть ответ... while (client.available()) { // Считываем принятый байт symbol = client.read(); // Для отладки пишем его в консоль Serial.print(symbol); // Сравниваем его с маской if (symbol == token[i] || token[i] == '?') { // Если сравнение успешно, то проверяем, не дошли ли мы до // цифр в названии файла if ((token[i] == '?') && (j < 2)) { imageId[j] = symbol; ++j; } ++i; } else { // Если сравнение не удалось, то сбрасываем счетчик i = 0; j = 0; } } Serial.println(""); } // останавливаем клиент client.stop(); } void readIconFromFile() { int linesCounter = 0; char byteValue; // OpenWeatherMap возвращает больше иконок, чем у нас есть. // Поэтому происходит небольшое переопределение // Добавляем расширение к имени файла char filename[16]; strcpy(filename, imageId); strcat(filename, ".pbm"); // Окрываем нужный файл File dataFile = SD.open(filename); if (dataFile) { // Пропускаем ненужное. Ищем начало четвертой строки while (linesCounter < 3) { byteValue = dataFile.read(); if (byteValue == '\n') ++linesCounter; } // Обнуляем имеющийся массив-изображение for (int i = 0; i < 8; ++i) { iconBytes[i] = 0; } // Считываем данные, выставляя единички в местах массива, // соответствующих единичкам в PBM-файле for (int i = 0; i < 64; ++i) { // Считанный символ - это один бит if (dataFile.read() == '1') iconBytes[i / 8] |= 1 << (i % 8); } } else { // Если чтение не удалось (например, файл не был найден), // ничего не считываем } // Закрываем файл после чтения dataFile.close(); } void hook() { // Во время работы запрашиваем новую погоду 1 раз в 15 минут if (millis() - startTime >= 15UL * 60UL * 1000UL) { readIconName(); readIconFromFile(); startTime = millis(); } // Очищаем экран marix.clear(); // Выводим погоду на индикатор marix.put_pic(0, 0, 8, 8, iconBytes, MULTIPLY, RED + GREEN, TOP_LAYER); } void setup() { // Инициализируем периферию Serial.begin(9600); Ethernet.begin(mac, ip); pinMode(ETHERNET_CHIP_SELECT_PIN, OUTPUT); if (!SD.begin(SD_CHIP_SELECT_PIN)) { Serial.println("Card failed, or not present!"); //Если по какой-то причине не удается начать работу //с картой памяти, то выводим ошибку } startTime = millis(); // После запуска запрашиваем текущую погоду readIconName(); readIconFromFile(); // Запускаем функцию отображения marix.display(hook); } void loop() { }