Commit 00dcf548 authored by Nelso Jost's avatar Nelso Jost

NEW: merged esplogger work and better structure established

parent 6c202d31
EMM Data Logger
EMM Meteorolog
Copyright (C) 2015 Nelso G. Jost
This program is free software: you can redistribute it and/or modify
......
PORT :=
BAUD := 115200
PIOBOARD = esp12e
PIOPROJ = firmware/esplogger
PIODIR = .pio
.PHONY: firmware monitor reset getport
all: help
install-platformaio:
pip install platformio
firmware:
@ echo "$$PIO_BUILD" | sh
@ $(MAKE) monitor
monitor: getport
picocom /dev/$(PORT) -b $(BAUD)
reset: getport
@ echo "-----------------------------------------"
@ echo "Reseting the board"
esptool.py --port /dev/$(PORT) run
@ python -c "import time; time.sleep(1)"
getport:
@ $(eval PORT := `python utils/getport.py`)
@ echo $(PORT)
example-blink:
$(eval PIOPROJ := examples/blink)
@ echo "$$PIO_BUILD" | sh
example-wifiscan:
$(eval PIOPROJ := examples/wifiscan)
@ echo "$$PIO_BUILD" | sh
$(MAKE) monitor
example-sdcardinfo:
$(eval PIOPROJ := examples/sd_card_info)
@ echo "$$PIO_BUILD" | sh
$(MAKE) monitor
help:
@ echo "$$HELP_MAKEFILE"
define HELP_MAKEFILE
Usage: make <target> where <target> can be:
firmware Build and upload the esplogger firmware using platformio
monitor Start the picocom serial monitor (autodetect port)
reset Attempt a soft reset of the ESP devkit board
example-____ Build and upload one of the examples/ projects:
blink -- turn on and off the led on pin 2
wifiscan -- detect and print all available SSIDs
endef
export HELP_MAKEFILE
define PY_GET_PORT
import os
ports = [x for x in os.listdir("/dev") if x.startswith("ttyUSB")
or x.startswith("ttyACM")]
if ports and isinstance(ports[0], str):
print(ports[0])
else:
print("Error: Unable to find a ttyUSB/ttyACM serial port")
raise SystemExit(1)
endef
export PY_GET_PORT
define PIO_BUILD
mkdir -p $(PIODIR)
rm -rf $(PIODIR)/src
platformio init --board $(PIOBOARD) -d $(PIODIR)
cp -rf $(PIOPROJ)/* $(PIODIR)/src/
cd $(PIODIR) && platformio run -t upload
endef
export PIO_BUILD
Purpose
-------
Data logger firmware that runs on the ESP12e NodeMCU board connected an Arduino via software serial for sensor reading. This firmware is being designed to accomplish the following tasks:
* Read sensor data from the Arduino board (established platform for plugging sensors);
* Save the data locally onto an SD card;
* Attempt to send the data onto the server (if fail, try again later);
* Serial REPL (Read-Eval-Print-Loop) interpreter for sending commands;
** Used on initial setup and debugging tasks;
This software is part o the project EMM at CTA-UFRGS. See the official page for more details:
http://cta.if.ufrgs.br/projects/estacao-meteorologica-modular/wiki/Wiki
Usage
-----
The Makefile present on the root directory provide a quick commands for the most commom operations. Type "make" or "make help" for showing the help message. Some commands require external tools to be installed, like Platformio.
The project firmware is under the "firmware/" directory and is ArduinoIDE-compatible. Alternatively you can build/upload it via terminal using "make firmware" command, that uses the excelent PlatformIO tool (use "make install-platformio" if not present).
The examples folder contains several Arduino-IDE compatible little projects for demonstration of key features of the ESP12e.
Development
-----------
The software is still on its early stages, so new functionality will be added frequently.
#include <Arduino.h>
#define LED_PIN 2
#define SLEEP_INTERVAL 500 // milliseconds
void setup()
{
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_PIN, HIGH);
delay(SLEEP_INTERVAL);
digitalWrite(LED_PIN, LOW);
delay(SLEEP_INTERVAL);
}
#include <Arduino.h>
#define LED_PIN 2
#define SLEEP_INTERVAL 500 // milliseconds
void setup()
{
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
}
void loop()
{
digitalWrite(LED_PIN, HIGH);
delay(SLEEP_INTERVAL);
digitalWrite(LED_PIN, LOW);
delay(SLEEP_INTERVAL);
}
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 10;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("\nInitializing SD card...");
// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card inserted?");
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
Serial.println("Wiring is correct and a card is present.");
}
// print the type of card
Serial.print("\nCard type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}
// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
return;
}
// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC);
Serial.println();
volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize *= 512; // SD card blocks are always 512 bytes
Serial.print("Volume size (bytes): ");
Serial.println(volumesize);
Serial.print("Volume size (Kbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Mbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}
void loop(void) {
}
/*
* CREDITS: https://github.com/platformio/platform-espressif8266
*
* This sketch demonstrates how to scan WiFi networks.
* The API is almost the same as with the WiFi Shield library,
* the most obvious difference being the different file you need to include:
*/
#include <Arduino.h>
#include "ESP8266WiFi.h"
void setup()
{
Serial.begin(115200);
// Set WiFi to station mode and disconnect from an AP
// if it was previously connected
// WiFi.mode(WIFI_STA);
// WiFi.disconnect();
// delay(100);
// Serial.println("Setup done");
}
void loop()
{
Serial.print("\nScanning wifi networks...");
Serial.flush();
int n = WiFi.scanNetworks();
Serial.println(" done!\n");
Serial.flush();
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found:");
Serial.println("-------------------------");
for (int i = 0; i < n; ++i)
{
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
delay(10);
}
}
Serial.println("");
Serial.println("Waiting 5 secs...");
Serial.flush();
// Wait a bit before scanning again
delay(5000);
}
/*
*/
#include <Arduino.h>
#include "wifi.h"
char read_char = 0;
String command = "";
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print("> ");
}
void loop()
{
if ((read_char == 13) || (command.endsWith(";")))
{
execute_board_command(command);
Serial.println();
Serial.print("> ");
command = "";
}
else
{
Serial.print(read_char);
command += read_char;
};
Serial.flush();
while (!Serial.available()) {};
read_char = Serial.read();
}
int execute_board_command(String command)
{
if (command == "wifiscan;")
{
wifiscan();
}
else if (command == "ls")
{
}
else
{
Serial.println("");
Serial.print("[Error] Invalid command: \"");
Serial.print(command);
Serial.println("\"");
}
}
/*
* CREDITS: https://github.com/platformio/platform-espressif8266
*
* This sketch demonstrates how to scan WiFi networks.
* The API is almost the same as with the WiFi Shield library,
* the most obvious difference being the different file you need to include:
*/
#include <Arduino.h>
#include "ESP8266WiFi.h"
void wifiscan(void)
{
Serial.println();
Serial.print("Scanning wifi networks...");
Serial.flush();
int n = WiFi.scanNetworks();
Serial.println(" done!\n");
Serial.flush();
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found:");
Serial.println("-------------------------");
for (int i = 0; i < n; ++i)
{
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
delay(10);
}
}
}
#ifndef WIFI_H
#define WIFI_H
void wifiscan(void);
#endif
BOARD := uno
PROJDIR := firmware/adafruit_bmp
PIOSETUP := python ../../utils/piosetup.py
PIODIR := .pio
.PHONY: monitor uno due nano mega clean
all:
$(MAKE) $(BOARD)
uno:
$(PIOSETUP) --board uno --project-dir $(PROJDIR) --pio-dir $(PIODIR)
$(MAKE) monitor
due:
$(PIOSETUP) --board diecimilaatmega328 --pio-dir $(PIODIR)
nano:
$(PIOSETUP) --board nanoatmega328 --pio-dir $(PIODIR)
mega:
$(PIOSETUP) --board megaatmega2560 --pio-dir $(PIODIR)
monitor:
picocom --baud $(shell $(GET_BAUD)) $(shell $(GET_PORT))
clean:
rm -rf .pio .travis.yml
define GET_BAUD
cat $(PROJDIR)/*.ino | grep '^#define BAUDRATE' | awk '{print $$3}'
endef
define GET_PORT
platformio device list | head -1
endef
/***************************************************************************
This is a library for the BMP085 pressure sensor
Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
----> http://www.adafruit.com/products/391
----> http://www.adafruit.com/products/1603
These displays use I2C to communicate, 2 pins are required to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Written by Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
***************************************************************************/
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#ifdef __AVR_ATtiny85__
#include "TinyWireM.h"
#define Wire TinyWireM
#else
#include <Wire.h>
#endif
#include <math.h>
#include <limits.h>
#include "Adafruit_BMP085_U.h"
static bmp085_calib_data _bmp085_coeffs; // Last read accelerometer data will be available here
static uint8_t _bmp085Mode;
#define BMP085_USE_DATASHEET_VALS (0) /* Set to 1 for sanity check */
/***************************************************************************
PRIVATE FUNCTIONS
***************************************************************************/
/**************************************************************************/
/*!
@brief Writes an 8 bit value over I2C
*/
/**************************************************************************/
static void writeCommand(byte reg, byte value)
{
Wire.beginTransmission((uint8_t)BMP085_ADDRESS);
#if ARDUINO >= 100
Wire.write((uint8_t)reg);
Wire.write((uint8_t)value);
#else
Wire.send(reg);
Wire.send(value);
#endif
Wire.endTransmission();
}
/**************************************************************************/
/*!
@brief Reads an 8 bit value over I2C
*/
/**************************************************************************/
static void read8(byte reg, uint8_t *value)
{
Wire.beginTransmission((uint8_t)BMP085_ADDRESS);
#if ARDUINO >= 100
Wire.write((uint8_t)reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
Wire.requestFrom((uint8_t)BMP085_ADDRESS, (byte)1);
#if ARDUINO >= 100
*value = Wire.read();
#else
*value = Wire.receive();
#endif
Wire.endTransmission();
}
/**************************************************************************/
/*!
@brief Reads a 16 bit value over I2C
*/
/**************************************************************************/
static void read16(byte reg, uint16_t *value)
{
Wire.beginTransmission((uint8_t)BMP085_ADDRESS);
#if ARDUINO >= 100
Wire.write((uint8_t)reg);
#else
Wire.send(reg);
#endif
Wire.endTransmission();
Wire.requestFrom((uint8_t)BMP085_ADDRESS, (byte)2);
#if ARDUINO >= 100
*value = (Wire.read() << 8) | Wire.read();
#else
*value = (Wire.receive() << 8) | Wire.receive();
#endif
Wire.endTransmission();
}
/**************************************************************************/
/*!
@brief Reads a signed 16 bit value over I2C
*/
/**************************************************************************/
static void readS16(byte reg, int16_t *value)
{
uint16_t i;
read16(reg, &i);
*value = (int16_t)i;
}
/**************************************************************************/
/*!
@brief Reads the factory-set coefficients
*/
/**************************************************************************/
static void readCoefficients(void)
{
#if BMP085_USE_DATASHEET_VALS
_bmp085_coeffs.ac1 = 408;
_bmp085_coeffs.ac2 = -72;
_bmp085_coeffs.ac3 = -14383;
_bmp085_coeffs.ac4 = 32741;
_bmp085_coeffs.ac5 = 32757;
_bmp085_coeffs.ac6 = 23153;
_bmp085_coeffs.b1 = 6190;
_bmp085_coeffs.b2 = 4;
_bmp085_coeffs.mb = -32768;
_bmp085_coeffs.mc = -8711;
_bmp085_coeffs.md = 2868;
_bmp085Mode = 0;
#else
readS16(BMP085_REGISTER_CAL_AC1, &_bmp085_coeffs.ac1);
readS16(BMP085_REGISTER_CAL_AC2, &_bmp085_coeffs.ac2);
readS16(BMP085_REGISTER_CAL_AC3, &_bmp085_coeffs.ac3);
read16(BMP085_REGISTER_CAL_AC4, &_bmp085_coeffs.ac4);
read16(BMP085_REGISTER_CAL_AC5, &_bmp085_coeffs.ac5);
read16(BMP085_REGISTER_CAL_AC6, &_bmp085_coeffs.ac6);
readS16(BMP085_REGISTER_CAL_B1, &_bmp085_coeffs.b1);
readS16(BMP085_REGISTER_CAL_B2, &_bmp085_coeffs.b2);
readS16(BMP085_REGISTER_CAL_MB, &_bmp085_coeffs.mb);
readS16(BMP085_REGISTER_CAL_MC, &_bmp085_coeffs.mc);
readS16(BMP085_REGISTER_CAL_MD, &_bmp085_coeffs.md);
#endif
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
static void readRawTemperature(int32_t *temperature)
{
#if BMP085_USE_DATASHEET_VALS
*temperature = 27898;
#else
uint16_t t;
writeCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READTEMPCMD);
delay(5);
read16(BMP085_REGISTER_TEMPDATA, &t);
*temperature = t;
#endif
}
/**************************************************************************/
/*!
*/
/**************************************************************************/
static void readRawPressure(int32_t *pressure)
{
#if BMP085_USE_DATASHEET_VALS
*pressure = 23843;
#else
uint8_t p8;
uint16_t p16;
int32_t p32;
writeCommand(BMP085_REGISTER_CONTROL, BMP085_REGISTER_READPRESSURECMD + (_bmp085Mode << 6));
switch(_bmp085Mode)
{
case BMP085_MODE_ULTRALOWPOWER:
delay(5);
break;
case BMP085_MODE_STANDARD:
delay(8);
break;
case BMP085_MODE_HIGHRES:
delay(14);
break;
case BMP085_MODE_ULTRAHIGHRES:
default:
delay(26);
break;
}
read16(BMP085_REGISTER_PRESSUREDATA, &p16);
p32 = (uint32_t)p16 << 8;
read8(BMP085_REGISTER_PRESSUREDATA+2, &p8);
p32 += p8;
p32 >>= (8 - _bmp085Mode);
*pressure = p32;
#endif
}
/**************************************************************************/
/*!
@brief Compute B5 coefficient used in temperature & pressure calcs.
*/
/**************************************************************************/
int32_t Adafruit_BMP085_Unified::computeB5(int32_t ut) {
int32_t X1 = (ut - (int32_t)_bmp085_coeffs.ac6) * ((int32_t)_bmp085_coeffs.ac5) >> 15;
int32_t X2 = ((int32_t)_bmp085_coeffs.mc << 11) / (X1+(int32_t)_bmp085_coeffs.md);
return X1 + X2;
}
/***************************************************************************
CONSTRUCTOR
***************************************************************************/
/**************************************************************************/
/*!
@brief Instantiates a new Adafruit_BMP085_Unified class
*/
/**************************************************************************/
Adafruit_BMP085_Unified::Adafruit_BMP085_Unified(int32_t sensorID) {
_sensorID = sensorID;
}
/***************************************************************************