Paso 4: Cargar y configurar el código
- Abra weather_to_led.ino en el IDE de Arduino y configurar después las cosas
- Puertos de LED (los puertos PWM de la placa están marcados con una [ ~ ])
- Botón de Puerto
- Hora de dormir
- Puede cambiar la ruta del archivo de secuencia de comandos y configuración
- SMTPServerUrl es la dirección del servidor SMTP
- SMTPServerPort es el número de puerto del servidor SMTP
- SMTPUsername es el nombre de usuario de tu cuenta de correo
- SMTPPassword es la contraseña para su cuenta de correo
- Dirección de correo electrónico es la dirección de correo a su cuenta de correo
- Tema es el tema del correo enviado por esta secuencia de comandos
- Nota: La conexión no es sequre. Informaciones son no cifrado
CITY_NAME_LED CITY_NAME1;MIN_TEMP;MAX_TEMP;MIN_CLOUDS;MAX_CLOUDS;MIN_RAIN;MAX_RAIN;MESSAGE;E-MAIL; CITY_NAME2;... [...] [EMPTY LINE]
- CITY_NAME_LED es el nombre de la ciudad cuyos datos deben mostrarse mediante LEDs.
- Cada línea siguiente define un mensaje que debe enviarse al correo electrónico si se cumplen las condiciones dadas * según los datos meteorológicos de la ciudad definida en las líneas del principio. (CITY_NAME1 en el bloque de código)
- Las temperaturas se miden en grados Celsius, las nubes en por ciento (0% = cielo azul) y lluvia se mide en milímetros por metro cuadrado, caído en las últimas horas 3.
* Que significa que para cada valor medido debe ser x MIN_VALUE < = x y x < = MAX_VALUE.
weather_to_led.ino:
#define MAX_MESSAGE_LENGTH 128#define MAX_CITY_LENGTH 20 #define MAX_COMMAND_LENGTH (MAX_CITY_LENGTH + 30) #define MAX_MAILADDR_LENGTH 30#define SLEEP_TIME 3600 #define LOOP_DELAY 250 #define BUTTON_PIN 2 char SCRIPT_FILE[] = "/home/root/weather.py"; char CONFIG_FILE[] = "/home/root/config.txt"; char MAIL_FILE[] = "/home/root/mail.py";/* * Contains the IO port numbers for one RGB-LED. We use ports with * PWM to mix the colours. * Port 0 means, this LED is not used or connected. */ struct RGB_LED { int red; int green; int blue; };/* * Declaration of our 3 used led's. Each uses only two ports. So we * are able to connect three led's to 6 PWM ports. */ struct RGB_LED temp = {3, 0, 5}; struct RGB_LED rain = {0, 6, 9}; struct RGB_LED clouds = {0, 10, 11};struct weather { float temp; float clouds; float rain; };/* * Enables one led. Therefor the pinmode ist set to * output. * led struct with port numbers */ void init_rgb_led(struct RGB_LED led) { // Set each led Port to output if (led.red != 0) pinMode(led.red, OUTPUT); if (led.green != 0) pinMode(led.green, OUTPUT); if (led.blue != 0) pinMode(led.blue, OUTPUT); // Switch led's off set_rgb_led(led, 0, 0, 0); }/* * Sets the color on a specific led. We use analogWrite and PWM to * mix the colors. * The led struct should have been initialized before. * led struct with port numbers and r,g,b values, which should be * set */ void set_rgb_led(struct RGB_LED led, int r, int g, int b) { // Writes the given values on our ports. The value must be inverted, // caused by our construction. if (led.red != 0) analogWrite(led.red, 255 - r); if (led.green != 0) analogWrite(led.green, 255 - g); if (led.blue != 0) analogWrite(led.blue, 255 - b); }/* * Given a temperature in celsius this function shows the value * by mixing the right colors together. * degree from 0 to 25 */ void set_temp(int degree) { int value; // Scale: 0 <= degree <= 25 if (degree > 25) degree = 25; if (degree < 0) degree = 0; // Calculate the LED value. (25 * 1 value = degree * 10; // Red led was to bright. So its value is divided by 2 set_rgb_led(temp, value / 2, 0, 255 - value); }/* * Given a propability this function * shows the value by mixing the right colors together. * propability as value from 0 to 100 */ void set_rain(int percent) { int value; // Accept only values between 0 and 100 degree if (percent > 100) percent = 100; if (percent < 0) percent = 0; value = (percent * 255) / 100; set_rgb_led(rain, 0, 255 - value, value); }/* * Given a propability this function * shows the value by mixing the right colors together. * propability as value from 0 to 100 */ void set_clouds(int percent) { int value; if (percent > 100) percent = 100; if (percent < 0) percent = 0; value = (percent * 255) / 100; set_rgb_led(clouds, value, value, 255 - value); // Rot durch Verdratung }/* * This function uses a python script to send a message to a given mail address * including the current weather informations. * * message is a pointer to our message string * w is a weather struct containing the current informations * mailaddr is a pointer to our target mail string */ char send_weather_mail(char *message, struct weather w, char* mailaddr) { FILE *fp; char buf[1024]; // Prepare a big string, which contains the command if (snprintf(buf, 1024, "python2.7 %s '%s' 'New weather informations:\n%s\n\nCurrent Weather:\nTemperature: %.1fC\nRaining: %dmm (last 3h)\nClouds: %d%%'", MAIL_FILE, mailaddr, message, w.temp, w.rain, w.clouds) <= 0) { return 0; } // Open a pipe and execute the command fp = popen(buf, "r"); if (fp == NULL) { return 0; } // Next close it if (pclose(fp) != 0) { return 0; } return 1; }/* * Given a city and a weather struct, this method reads * the current weather values and fills the struct with these. * Name of a city as string * Pointer to a weather struct * * 0 on failure and otherwise it is a success */ int readWeather(char *city, struct weather *w) { FILE *fp; char buf[MAX_COMMAND_LENGTH + 1]; // Build the command string, by adding path and city together if (snprintf(buf, (MAX_COMMAND_LENGTH + 1) * sizeof(char), "python2.7 %s '%s'", SCRIPT_FILE, city) <= 0) { return 0; } /* Execute the python script and write everything into a pipe * so we can read the result */ fp = popen(buf, "r"); if (fp == NULL) return 0; // Read the current weather values int erg = fscanf(fp, "%f\n%f\n%f", &(w->temp), &(w->clouds), &(w->rain)) == 3; // Close the pipe and check return value if (pclose(fp) != 0) { return 0; } return erg; }/* * Standard Arduino setup method */ void setup() { int i; //Pullup resistors -> negated Logic pinMode(BUTTON_PIN, INPUT_PULLUP); // Set baudrate for debugging Serial.begin(9600); // Initialize our 3 RGB-LEDs init_rgb_led(temp); init_rgb_led(rain); init_rgb_led(clouds); // Test our leds by showing an animation for (i = 0; i <= 100; i++) { set_temp(i / 4); delay(10); } for (i = 0; i <= 100; i++) { set_rain(i); delay(10); } for (i = 0; i <= 100; i++) { set_clouds(i); delay(10); } }/* * Updates the weather infomation. * onlyLeds does what it sounds like ;) */ void updateEverything(bool onlyLeds) { struct weather weather; FILE *fd; char city[MAX_CITY_LENGTH + 1]; char mailaddr[MAX_MAILADDR_LENGTH + 1]; char message[MAX_MESSAGE_LENGTH + 1]; int min_tmp, max_tmp, min_rain, max_rain, min_clouds, max_clouds; // Open the config file fd = fopen(CONFIG_FILE, "r"); // Error handling if (fd == NULL) { Serial.println("Could not find/open config file!\n"); sleep(SLEEP_TIME); return; } // First read the standart LED city name if (fscanf(fd, "%s\n", city) == 1) { // Print name for debugging Serial.println(city); if (readWeather(city, &weather)) { // Print values for debugging Serial.println(weather.temp); Serial.println(weather.clouds); Serial.println(weather.rain); // Refresh LED colors set_temp(weather.temp); set_clouds(weather.clouds); set_rain(weather.rain); } else { Serial.println("Error reading weather!\n"); } } else { Serial.println("Konnte Stadt nicht lesen!\n"); } // Read config file, until it ends while (!feof(fd) && !onlyLeds) { // Try to read one line and parse it if (fscanf(fd, "%[^;];%d;%d;%d;%d;%d;%d;%[^;];%[^;];\n", city, &min_tmp, &max_tmp, &min_clouds, &max_clouds, &min_rain, &max_rain, message, mailaddr) == 9) { // Print city for debugging Serial.println(city); if (readWeather(city, &weather)) { // Print values for debugging Serial.println(weather.temp); Serial.println(weather.clouds); Serial.println(weather.rain); // Check our conditions for giving a message if (min_tmp <= weather.temp && weather.temp <= max_tmp && min_clouds <= weather.clouds && weather.clouds <= max_clouds && min_rain <= weather.rain && weather.rain <= max_rain) { // Print the message Serial.println(message); // Send a mail if (!send_weather_mail(message, weather, mailaddr)) { Serial.println("Error sending message!\n"); } } } else { Serial.println("Error reading weather!\n"); } } else { Serial.println("Error reading config file!"); } } // Close the file and wait for button press fclose(fd); }void loop() { static int loop_count = 1000 * SLEEP_TIME; // So it is executet at beginning if (loop_count >= 1000 * SLEEP_TIME) { updateEverything(0); loop_count = 0; } if (digitalRead(BUTTON_PIN) == LOW) { // Switch led's off set_rgb_led(temp, 0, 0, 0); set_rgb_led(clouds, 0, 0, 0); set_rgb_led(rain, 0, 0, 0); updateEverything(1); } loop_count += LOOP_DELAY; delay(LOOP_DELAY); }