Skip to content

Instantly share code, notes, and snippets.

@victorvhs
Last active December 3, 2015 11:24
Show Gist options
  • Select an option

  • Save victorvhs/d9167cd0d97a2912e3ba to your computer and use it in GitHub Desktop.

Select an option

Save victorvhs/d9167cd0d97a2912e3ba to your computer and use it in GitHub Desktop.

Revisions

  1. victorvhs revised this gist Dec 3, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion apc.c
    Original file line number Diff line number Diff line change
    @@ -372,4 +372,4 @@ void loop()
    #if DEBUG
    // debug();
    #endif
    }
    }
  2. victorvhs created this gist Nov 20, 2015.
    375 changes: 375 additions & 0 deletions apc.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,375 @@
    #include <SPI.h>
    #include <SD.h>
    #include <Wire.h>
    #include "RTClib.h"

    /* Ciclos de trabalho */
    #define CYCLE_1S 1000UL
    #define CYCLE_5S 5000UL
    #define CYCLE_30S 30000UL
    #define CYCLE_60S 60000UL

    /* Pinos dos sensores */
    #define WIND_DIRECTION_PIN 0
    #define WIND_SPEED_PIN 2
    #define RAIN_GAUGE_PIN 3

    #define FILE_DATA "DATA.TXT"
    #define FILE_BACKUP "BACKUP.TXT"

    #define NETWORK_SSID "dl"
    #define NETWORK_PASSWORD "12345"
    #define SERVER_IP "172.16.0.1"

    #define DEBUG 1

    /* Ponteiro para o arquivo */
    File db;
    File backup;

    /* Ponteiro para o RTC */
    RTC_DS1307 rtc;

    /* Controle de ciclos */
    unsigned long saveReading = 0;
    unsigned long transmissionLastMillis = 0;


    /* Controle da velocidade do vento */
    unsigned long lastWindCheck = 0;
    volatile unsigned long lastWindIRQ = 0; /* Debouncing */
    volatile unsigned int windClicks = 0;

    /* Controla o índice pluviométrico */
    volatile unsigned long lastRainIRQ = 0; /* Debouncing */
    volatile unsigned int rainClicks = 0;

    struct Data {
    char * timestamp;
    char * windSpeed;
    char * windDirection;
    char * rainfall;
    };

    struct Data data;

    int foundPipe = 0;

    /////////////////////////////////////////////////////////////////////////////////////////
    extern unsigned int __bss_end;
    extern unsigned int __heap_start;
    extern void *__brkval;

    int freeMemory() {
    int free_memory;

    if((int)__brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
    else
    free_memory = ((int)&free_memory) - ((int)__brkval);

    return free_memory;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    uint8_t cycleCheck(unsigned long *lastMillis, unsigned long cycle)
    {
    unsigned long currentMillis = millis();

    if(currentMillis - *lastMillis >= cycle) {
    *lastMillis = currentMillis;
    return 1;
    }
    else
    return 0;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void debug()
    {
    Serial.print(F("Memoria livre: "));
    Serial.print(freeMemory());
    Serial.println(F(" "));
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void windspeedIRQ()
    {
    if (millis() - lastWindIRQ > 10)
    {
    lastWindIRQ = millis();
    windClicks++;
    }
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    float getWindSpeed()
    {
    float deltaTime = millis() - lastWindCheck;

    deltaTime /= 1000.0; /* Converte para segundos */

    float windSpeed = (float)windClicks / deltaTime;

    windClicks = 0; /* Reseta e começar a verificar por novos ventos */
    lastWindCheck = millis();

    windSpeed *= 2.4; // Km/h = 2.4 e MPH = 1.492

    return windSpeed;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void rainIRQ()
    {
    if (millis() - lastRainIRQ > 10)
    {
    lastRainIRQ = millis();
    rainClicks++;
    }
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    float getRainfall()
    {
    float rainfall = (rainClicks * 0.2794);
    rainClicks = 0; /* Reseta a quantidade de chuva após cada consulta */
    return rainfall;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    char * getWindDirection()
    {
    unsigned int val = analogRead(WIND_DIRECTION_PIN);

    char * windDirection = "ERRO"; /* Já define a msg de erro */

    if(val < 100) windDirection = "W";
    else if ((val > 170) && (val < 200)) windDirection = "NW";
    else if((val > 270) && (val < 400)) windDirection = "N";
    else if((val > 450) && (val < 550)) windDirection = "SW";
    else if((val > 610) && (val < 750)) windDirection = "NE";
    else if((val > 760) && (val < 800)) windDirection = "S";
    else if((val > 860) && (val < 890)) windDirection = "SE";
    else if(val > 900) windDirection = "E";

    return windDirection;
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void appendToFile()
    {
    char buffer[20];
    DateTime now = rtc.now();
    sprintf (buffer, "%d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());

    db = SD.open(FILE_DATA, FILE_WRITE);

    if (db) {

    db.print(buffer);
    db.print(",");
    db.print(getWindSpeed());
    db.print(",");
    db.print(getWindDirection());
    db.print(",");
    db.println(getRainfall());

    } else { Serial.println(F("Erro ao tentar adicionar nova linha")); }

    db.close();
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void sendFileContentsToBluetooth()
    {
    db = SD.open(FILE_DATA);

    if (db) {

    while (db.available()) {
    char readValue = db.read();

    Serial.write(highByte(readValue));
    Serial.write(lowByte(readValue));
    }

    db.close();

    } else {
    Serial.println(F("Erro ao abrir o arquivo para enviar ao bluetooth"));
    Serial.write("SEM SD");
    }
    }
    /////////////////////////////////////////////////////////////////////////////////////////

    void checkIncomingBluetoothRequest()
    {
    char command = 0, byteRead = 0;

    while (Serial.available()) {

    byteRead = Serial.read(); // lê o byte que chegou na serial

    if(byteRead == '*') foundPipe = 0;

    if(byteRead == '|') foundPipe++;

    if(foundPipe == 3 && byteRead != '|') {
    foundPipe = 0;
    command = byteRead;
    }
    }

    switch (command) {
    case '1':
    sendFileContentsToBluetooth();
    break;
    case '2':
    makeFileBackup();
    break;
    }

    }

    /////////////////////////////////////////////////////////////////////////////////////////

    void makeFileBackup()
    {
    db = SD.open(FILE_DATA);
    backup = SD.open(FILE_BACKUP, FILE_WRITE);

    if(!backup) {
    Serial.println(F("Erro ao tentar abrir arquivo de backup"));
    Serial.write("backup nao abre");
    }
    if(!db){
    Serial.println(F("Erro ao tentar abrir arquivo de dados"));
    Serial.write("dados nao abre");
    }

    while (db.available()) {
    char readValue = db.read();
    backup.print(readValue);
    }

    db.close();
    backup.close();

    SD.remove(FILE_DATA);
    Serial.write("OK");
    Serial.println("REMOVIDO");
    }

    /////////////////////////////////////////////////////////////////////////////////////////

    String SendCommandESP8266(String command, const int timeout, boolean debug)
    {
    String response = "";
    Serial.print(command);
    long int time = millis();

    while ((time + timeout) > millis()) {

    while (Serial.available()) {
    char c = Serial.read();
    response += c;
    }
    }

    if (debug)
    Serial.print(response);

    return response;
    }

    /////////////////////////////////////////////////////////////////////////////////////////

    void SendDataOverESP8266(char* queryString)
    {
    char temp[150];

    SendCommandESP8266("AT+RST\r\n", 5000, DEBUG); // RESET
    SendCommandESP8266("AT+CIOBAUD=9600\r\n", 5000, DEBUG);
    SendCommandESP8266("AT+CIPMUX=0\r\n", 5000, DEBUG); // single connection

    sprintf (temp, "AT+CWJAP=\"%s\",\"%s\"\r\n", NETWORK_SSID, NETWORK_PASSWORD);
    SendCommandESP8266(temp, 15000, DEBUG);

    sprintf (temp, "AT+CIPSTART=\"TCP\",\"%s\",80\r\n", SERVER_IP);
    SendCommandESP8266(temp, 15000, DEBUG);

    SendCommandESP8266("AT+CIPSEND=69\r\n", 5000, DEBUG);

    sprintf (temp, "GET /teste.php?%s HTTP/1.1\r\n", queryString);
    SendCommandESP8266(temp, 5000, DEBUG);

    sprintf (temp, "Host: %s\r\n", SERVER_IP);
    SendCommandESP8266(temp, 5000, DEBUG);

    SendCommandESP8266("\r\n\r\n", 2000, DEBUG);
    SendCommandESP8266("AT+CIPCLOSE\r\n", 2000, DEBUG);
    }

    ////////////////////////////////////////////////////////////////////////////////////////

    void setup()
    {
    Serial.begin(9600);

    /** Interrupção do anemômetro */
    pinMode(WIND_SPEED_PIN, INPUT);
    digitalWrite(WIND_SPEED_PIN, HIGH);
    attachInterrupt(0, windspeedIRQ, FALLING);

    /** Interrupção do pluviômetro */
    pinMode(RAIN_GAUGE_PIN, INPUT);
    digitalWrite(RAIN_GAUGE_PIN, HIGH);
    attachInterrupt(1, rainIRQ, FALLING);

    /*Serial.print(F("Iniciando SD card..."));
    pinMode(10, OUTPUT);
    if (!SD.begin(10)) {
    Serial.println(F("Inicializacao falhou!"));
    return;
    }*/

    Wire.begin(); // RTC
    rtc.begin(); // RTC

    int isSetupDate = rtc.readnvram(0); /* Recupera o valor na memória não-volátil */

    if (isSetupDate != 1) {
    rtc.writenvram(0, 0x1);
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); /* Inicia o módulo RTC 1307 */
    }

    Serial.println(F("Inicializacao pronta."));
    }

    /////////////////////////////////////////////////////////////////////////////////////////
    void loop()
    {
    if(cycleCheck(&saveReading, CYCLE_60S)) {
    char temp[200];
    DateTime now = rtc.now();
    sprintf (temp, "%d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());

    Serial.print(temp);
    Serial.print(';');
    Serial.print(getWindSpeed());
    Serial.print(';');
    Serial.print(getRainfall());
    Serial.print(';');
    Serial.print(getWindDirection());
    Serial.println(';');

    }



    #if DEBUG
    // debug();
    #endif
    }