Skip to content

brayanftobonc/estacion-meteorologica

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

Overview

Purpose and Scope

The estacion-meteorologica repository implements a complete Arduino-based meteorological station system that collects environmental sensor data, displays it in real-time on an OLED screen, logs it to local SD card storage, and transmits it to the Ubidots IoT cloud platform for remote monitoring and analysis.

This system is designed as a single, self-contained Arduino sketch running on an Arduino Mega 2560 microcontroller. It operates autonomously using a hardware timer interrupt to trigger periodic data acquisition cycles, ensuring precise timing without blocking operations.

This page provides a high-level overview of the system architecture, components, and operation. For detailed information about specific subsystems, see:

  • Hardware components and wiring: Hardware Components
  • Sensor implementation details: Sensor Integration
  • Display, storage, and cloud integration: System Operation
  • Timing and execution flow: Data Flow & Protocols
  • Configuration and deployment: Configuration and Setup

Sources: est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 1-322

System Components

The meteorological station consists of the following primary components:

Componente Type Interface Purpose
Arduino Mega 2560 Microcontroller ---- Main controller and data processor
DHT22 Digital Sensor Pin 2 (One-Wire) Temperature and humidity measurement
UV Sensor Analog Sensor A0 (UVOUT), A1 (REF_3V3) UV intensity measurement
LDR Analog Sensor A3 (SENSORLUZ) Ambient light level measurement
SSD1306 OLED Display I2C (0x3C) Real-time data visualization
SD Card Module Storage SPI (CS Pin 53) Local data logging to Datos.txt
ESP8266/Telemetry Unit WiFi Module Serial1 (115200 baud) Cloud data transmission
Status LED's Indicators Pins 3, 7 Visual feedback for light level and transmission

The system integrates these components through multiple communication protocols (I2C, SPI, Serial, One-Wire, analog) coordinated by the Arduino Mega's ATmega2560 processor.

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 5-48 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 75-124

Architecture Overview

Core Software Structure

flowchart LR
    subgraph est_meteorologica_via_ubidots.ino
        direction TB
        setupLines75-125[setup Lines 75-125] 
        loopLines127-12[loop Lines 127-12]
        ISRTIMER3_COMPA_vectLines312-321[ISR TIMER3_COMPA_vect Lines312-321]
        datosServerLines150-309[datosServer Lines 150-309]
        averageAnologReadLines132-142[averageAnologRead Lines 132-142]
        mapfloatLines144-147[mapfloat Lines 144-147]

    end
    subgraph External Library Objects
        direction TB
        dhtLine29[dht Line 29]
        displayAdafruit_SSD1306Line48[display Adafruit_SSD1306 Line 48]
        myFileLine14[myFile Line 14]
        Serial1HardwareUART[Serial1 Hardware UART]
    end

    subgraph Global State Variables
        direction TB
        Contador1Line7Timercounter[Contador1 Line 7 Timer counter]
        flow_controlLine54Request-responsesync[flow_control Line 54 Request-response sync]
        TEMPERATURAHUMEDADVALORPWM[TEMPERATURA HUMEDAD VALOR PWM]
        TOKENDEVICE_LABELVARIABLE_LABELs[TOKEN DEVICE_LABEL VARIABLE_LABEL's]
    end

    %% Direccionamientos
    setupLines75-125 --Initialize--> dhtLine29
    setupLines75-125 --Initialize--> displayAdafruit_SSD1306Line48
    setupLines75-125 --Configure--> ISRTIMER3_COMPA_vectLines312-321
    setupLines75-125 --Initialize SD--> myFileLine14
    loopLines127-12 -.Empty, all work done in ISR.-> ISRTIMER3_COMPA_vectLines312-321
    ISRTIMER3_COMPA_vectLines312-321 --Every 4s Calls--> datosServerLines150-309
    ISRTIMER3_COMPA_vectLines312-321 --Increments--> Contador1Line7Timercounter
    datosServerLines150-309 --Calls--> averageAnologReadLines132-142
    datosServerLines150-309 --Calls--> mapfloatLines144-147
    datosServerLines150-309 --Reads--> dhtLine29
    datosServerLines150-309 --Updates--> displayAdafruit_SSD1306Line48
    datosServerLines150-309 --Writes--> myFileLine14
    datosServerLines150-309 --Transmits via--> Serial1HardwareUART
    datosServerLines150-309 --Uses--> flow_controlLine54Request-responsesync
    datosServerLines150-309 --Uses--> TOKENDEVICE_LABELVARIABLE_LABELs

Loading

The system employs a monolithic single-file architecture where all functionality resides in est_meteorologica_via_ubidots.ino. The loop() function is intentionally empty, as all operational logic is triggered by the Timer3 interrupt service routine ISR(TIMER3_COMPA_vect).

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 75-125 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 127-128 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 312-321

Hardware Timer Interrupt Mechanism

flowchart LR
    subgraph Timer 3 Configuration in setup
        direction TB
        TCCR3A0Line95[TCCR3A = 0 Line 95] 
        TCCR3BWGM32bitLine104CTCMode[TCCR3 BWGM32 bit Line 104 CTC Mode]
        TCCR3BCS32CS30Line106Prescaler1024[TCCR3B CS32 CS30 Line 106 Prescaler 1024]
        OCR3A31249Line992speriod[OCR3A = 31249 Line 99 2s period]
        TIMSK3OCIE3ALine108Enableinterrupt[TIMSK3 OCIE3A Line 108 Enable interrupt]
    end
    subgraph Runtine Operation
        direction TB
        HardwareTimer316MHz1024[Hardware Timer3 16MHz / 1024]
        ComparetoOCR34Every2second[Compare to OCR34 Every 2 second]
        ISRTIMER3_COMPA_vectLine312[ISR TIMER3_COMPA_vect Line 312]
        Contador1++Line313[Contador1++ Line 313]
        ifContador12Line314[if Contador1 = 2 Line 314]
        datosServerLine319[datosServer Line 319]

    end

    TCCR3A0Line95 --> HardwareTimer316MHz1024
    TCCR3BWGM32bitLine104CTCMode --> HardwareTimer316MHz1024
    TCCR3BCS32CS30Line106Prescaler1024 --> HardwareTimer316MHz1024
    OCR3A31249Line992speriod --> HardwareTimer316MHz1024
    TIMSK3OCIE3ALine108Enableinterrupt --> HardwareTimer316MHz1024
    HardwareTimer316MHz1024 --Every 2s--> ComparetoOCR34Every2second
    ComparetoOCR34Every2second --> ISRTIMER3_COMPA_vectLine312
    ISRTIMER3_COMPA_vectLine312 --> Contador1++Line313
    Contador1++Line313 --> ifContador12Line314
    ifContador12Line314 --False: Return--> ISRTIMER3_COMPA_vectLine312
    ifContador12Line314 --True: 4s elapse--> datosServerLine319
Loading

The system uses Timer3 in CTC mode (Clear Timer on Compare Match) with a prescaler of 1024 and compare value of 31249 to generate interrupts every 2 seconds. The ISR maintains a counter Contador1 that triggers the main data acquisition function datosServer() every 4 seconds (when counter reaches 2).

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 90-111 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 312-321

Data Flow and Processing

Complete Data Pipeline

flowchart LR
    subgraph interrupt Trigger Every 4s
        direction TB
        ISRTIMER3_COMPA_vectLine312[ISR TIMER3_COMPA_vect Line 312]
        Contador12Line314[Contador1 = 2 Line 314]
        datosServerLine319[datosServer Line 319]        
    end
    subgraph Flow Control Check
        direction TB
        flow_controlflagLine54,160[flow_control flag Line 54, 160]
        flow_controltrue?{flow_control = true?}
    end

    subgraph Response Handling
        direction TB
        Serial1.availableLine295[Serial1.available Line 295]
        Readtelemetry_unitLines296-298[Read telemetry_unit Lines 296-298]
        flow_controltrueLine298[flow_control true Line 298]
    end

    subgraph Sensor Reading
        direction TB
        dht.readTemperaturedht.readHumidityLines161-162[dht.readTemperatured ht.readHumidity Lines 161-162]
        averageAnalogReadUVOUTaverageAnalogReadREF_3V3Lines164-165[averageAnalogRead UVOUT average AnalogRead REF_3V3 Lines 164-165]
        outputVoltagecalculationmapfloattouvIntensityLines167-169[outputVoltage calculation mapfloat to uvIntensity Lines 167-169]
        analogReadSENSORLUZmaptoPWMLines215-216[analogReadSENSORLUZ map to PWM Lines 215-216]
    end

    subgraph Data Processing y Display
        direction TB
        display.clearDisplaydisplay.printlnLines172-233[display.clearDisplay display.println Lines 172-233]
        dtostrfconversionsLines236-239[dtostrf conversions Lines 236-239]
        sprintfUbidotscommandLines242-249[sprint fUbidots command Lines 242-249]
    end

    subgraph Output Operations
        direction TB
        SD.openDatos.txtmyFile.printLines264-276[SD.openDatos.txt myFile.print Lines 264-276]
        Serial1.printcommandLine256[Serial1.printcommand Line 256]
        flow_controlfalseLine262[flow_control = false Line 262]
    end

    ISRTIMER3_COMPA_vectLine312 --> Contador12Line314
    Contador12Line314 --Yes--> datosServerLine319
    datosServerLine319 --> flow_controlflagLine54,160
    flow_controlflagLine54,160 --> flow_controltrue?
    flow_controltrue? --No: Read response --> Serial1.availableLine295
    Serial1.availableLine295 --> Readtelemetry_unitLines296-298
    Readtelemetry_unitLines296-298 --> flow_controltrueLine298
    flow_controltrueLine298 -.Next cycle.-> flow_controlflagLine54,160
    flow_controltrue? --> dht.readTemperaturedht.readHumidityLines161-162
    dht.readTemperaturedht.readHumidityLines161-162 --> averageAnalogReadUVOUTaverageAnalogReadREF_3V3Lines164-165
    averageAnalogReadUVOUTaverageAnalogReadREF_3V3Lines164-165 --> outputVoltagecalculationmapfloattouvIntensityLines167-169
    outputVoltagecalculationmapfloattouvIntensityLines167-169 --> analogReadSENSORLUZmaptoPWMLines215-216
    analogReadSENSORLUZmaptoPWMLines215-216 --> display.clearDisplaydisplay.printlnLines172-233
    display.clearDisplaydisplay.printlnLines172-233 --> dtostrfconversionsLines236-239
    dtostrfconversionsLines236-239 --> sprintfUbidotscommandLines242-249
    sprintfUbidotscommandLines242-249 --> SD.openDatos.txtmyFile.printLines264-276
    SD.openDatos.txtmyFile.printLines264-276 --> Serial1.printcommandLine256
    Serial1.printcommandLine256 --> flow_controlfalseLine262
    flow_controlfalseLine262 -.Next cycle.-> flow_controlflagLine54,160
Loading

The data pipeline implements a request-response flow control mechanism using the flow_control boolean flag:

  1. When flow_control is True: The system reads all sensors, processes data, updates the OLED display, logs to SD card, transmits to Ubidots via Serial1, and sets flow_control to false

  2. When flow_control is False: The system waits for a response from the telemetry unit on Serial1, and upon receiving data, sets flow_control back to True

This prevents command queue overflow in the ESP8266 telemetry unit by ensuring only one command is in flight at a time.

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 150-309

Sensor Data Processing Details

Sensor Reading Method Processing Output Format
DHT22 Temperature dht.readTemperature() Direct read, stored inTEMPERATURA Integer °C, converted to string via dtostrf()
DHT22 Humidity dht.readHumidity() Direct read, stored inHUMEDAD Integer %, converted to string via dtostrf()
UV Sensor averageAnalogRead(UVOUT)8 samples Voltage calculation, mapfloat()to 0.0-15.0 scale uvLevel raw value, categorized text display
LDR Light analogRead(SENSORLUZ) map()to PWM 0-255, threshold at 80 VALOR raw value, ON/OFF LED control

All analog sensors use noise reduction techniques: the UV sensor employs averageAnalogRead() which takes 8 samples and returns the average, while the LDR uses direct reading with PWM mapping for LED brightness control.

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 161-169 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 215-216 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 132-147

Key System Characteristics

Communication Protocols

flowchart LR
    subgraph Arduino Mega ATmega2560
        direction TB
        SerialUART0115200baudLine76[Serial UART0 115200 baud Line 76]
        Serial1UART1115200baudLine77[Serial1 UART1 115200 baud Line 77]
        SPILines10,13[SPI Lines 10, 13]        
        WireLines17,48[Wire I2C Lines 17, 48]        
        GPIOPinsDigitalyAnalog[GPIO Pins Digital and Analog]        
    end

SerialUART0115200baudLine76 --Debug output--> PC/SerialMonitor[PC/Serial Monitor]
Serial1UART1115200baudLine77 --Ubidots commands telemetry_unit array--> ESP8266WiFiModuleTelemetryUnit[ESP8266 WiFi Module Telemetry Unit]
ESP8266WiFiModuleTelemetryUnit --Wifi HTTP POST--> UbidotsCloudDevice:Mega1[Ubidots Cloud Device: Mega1]
SPILines10,13 --CS Pin 53 myFile object--> SDCardModuleDatos.txt[SDCard Module Datos.txt]
WireLines17,48 --0x3c address display object--> SSD1306OLEDDisplay128x64[SSD1306 OLED Display 128x64]
GPIOPinsDigitalyAnalog --Pin 2 dht object--> DHT22Sensor[DHT22 Sensor]
GPIOPinsDigitalyAnalog --Pin's A0, A1--> UVSensor[UV Sensor]
GPIOPinsDigitalyAnalog --Pin A3--> LDRSensor[LDR Sensor]
GPIOPinsDigitalyAnalog --Pin's 3, 7--> StatusLED's[Status LED's]
Loading

The system employs four distinct communication protocols coordinated by the Arduino Mega:

  • UART0 (Serial): Debug output to PC at 115200 baud
  • UART1 (Serial1): Bidirectional communication with ESP8266 telemetry unit for cloud transmission
  • I2C (Wire): Communication with SSD1306 OLED display at address 0x3C
  • SPI: High-speed data transfer to SD card module with chip select on pin 53

- est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 76-77 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 13-48

Ubidots Cloud Integration

The system constructs custom protocol commands for transmission to Ubidots via the ESP8266 telemetry unit. The command format follows this structure:

init#UbidotsESP8266Mega1/1.0|POST|TOKEN=>DEVICE_LABEL=>variable:value,variable:value|end#final

Example command built in datosServer():

init#UbidotsESP8266Mega1/1.0|POST|BBFF-Uya1LL5n6F8Jn62mthoTfNI2Qd8VuW|Mega1=>Temperatura:25.00,Humedad:60.00,lUZ:512.00,Uv:227.00|end#final

This command is constructed using multiple sprintf() calls

est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 242-249 and transmitted via Serial1.print(command)

est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 256 The telemetry unit parses this command and executes an HTTP POST request to the Ubidots API.

- est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 50-65 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 236-262

Storage and Logging

Local data persistence is achieved through the SD card module using the Arduino SD library. Data is appended to a file named Datos.txt in CSV-like format:

TEMPERATURA:25°C,HUMEDAD:60%,INTENSIDAD LUZ:512,RANGO:227

The file operations occur within datosServer()

- est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 264-280

  1. Open file in write mode: ``` myFile = SD.open("Datos.txt", FILE_WRITE)``
  2. Write sensor data with labels
  3. Close file: myFile.close()

Error handling is implemented to detect file operation failures, with error messages printed to the Serial port.

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 9-14 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 113-123 - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 264-280

System Capabilities Summary

The meteorological station provides the following capabilities:

Capability Implementation Update Frequency
Environmental monitoring DHT22, UV sensor, LDR Every 4 seconds
Real-time display SSD1306 OLED with live readings and status Every 4 seconds
Local data logging SD card CSV append operations Every 4 seconds
Cloud telemetry Ubidots HTTP POST via ESP8266 Every 4 seconds (with flow control)
UV categorization Threshold-based classification (8 levels) Real-time
Automatic light control PWM-based LED dimming based on ambient light Real-time
Interrupt-driven timing Timer3 hardware interrupts for precise scheduling 2-second ISR, 4-second data cycle

The system operates autonomously and continuously once powered on, with all operations coordinated by the Timer3 interrupt mechanism. No manual intervention is required for normal operation, and the empty loop() function ensures minimal overhead between interrupt cycles.

Sources: - est_meteorologica_via_ubidots/est_meteorologica_via_ubidots.ino 1-322

About

Sistema IoT con Arduino Mega que monitorea temperatura, humedad, luz y radiación UV. Incluye pantalla OLED, almacenamiento en SD y envío de datos a Ubidots. Usa interrupciones por timer para lecturas periódicas cada 4 segundos.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages