Precision Gauge
We use the ESP8266 chip which gathers temperature data from a sensor and then forwards it via REST to a Raspberry Pi, where it's stored in a database.
We use the ESP8266 chip which gathers temperature data from a sensor and then forwards it via REST to a Raspberry Pi, where it's stored in a database.
In the first part of this series of articles, we demonstrated how to build a functioning development environment. This time we focus our attention on activating and using the Wifi interface on the ESP8266 [1]. This module reads measurement values from the LM75 temperature sensor using an I2C-Bus, and transmits the data via a web interface to a MySQL database that is running on a Raspberry Pi.
I2C
The serial I2C data bus is intended for communication over short distances i.e. within boards or devices. The data flows over two lines. These include the data line SDA and the clock line SCL. Both of these lines are pulled via pullup resistors to a positive potential.
The busmaster always initiates communication. The bus has a 7 bit address range which allows for a maximum of 128 devices. There are 16 reserved addresses, so a total of 112 remain available. Usually you are only able to select the three lower bits of the addresses for clients. The upper bits are hardwired. You will find the potential addresses for each component in its data sheet. The Component Examples table contains some example values.
The bus transmits data by byte or word. It does so at a speed of between 100 kbit/s bidirectionally (default) and 5 Mbit/s unidirectionally (Ultra Fast Mode). There are several ways to increase the range of the I2C Bus. These include limiting the pull up resistors to tunneling with CAN bus drivers.
As you read through this project, remember the sensor is battery powered. While operating, the ESP8266 consumes up to 200 milliamperes. If you run the sensor continuously, you'll need a battery that can supply this. A much more elegant and economical solution is to switch on the module for 1-2 seconds at a time, during which the sensor will identify and transmit the measurement values. After completing these tasks, the module can then deactivate.
Table 1
Component Examples
Model | Function | Address Range | Comment |
---|---|---|---|
PCF8574 |
Port Expander |
0x20-0x27 |
– |
PCF8574A |
Port Expander |
0x38-0x3F |
a different Address space, otherwise constructed identically to the PCF8574 |
PCF8591 |
A/D- and D/A converter |
0x90-0x9F |
– |
PCF8583 |
clock/calendar + 240 x 8-Bit-RAM |
0xA0-0xA2 |
– |
As such, try to work out how many measurements you actually need. Do you really need one measurement per second or is once an hour enough? The sensor designers have also clearly given such questions some thought and have equipped it with an energy saving function. This makes it possible to power down the ESP8266 and the LM75 to a level where only a few microamperes are consumed. If you want to avoid using a complex power supply, make sure the semi-conductor is idle when it's not needed.
During the initial test run, the ESP8266 takes one measurement each minute and transmits the results via a REST interface to the database. Both of the ICs sleep the rest of the time. You can increase this interval of inactivity in order to save energy. For example, measurements every fifteen minutes are perfectly fine for a private weather station.
Look at the circuit diagram in Figure 1 for the project and at details on building the first prototype in Figure 2.
You will see two jumpers on the circuit diagram. These are used to shift the ESP8266 into bootloader mode. If they are closed, then a new program will load. When they are open, the micro controller operates normally and executes the program you've uploaded.
You may already be acquainted with the LM75 from our series on the I2C-Bus [3] (see the I2C box). This component delivers temperature values in plain text. In the switching detailed in the diagram, the address for the LM75 is 0x48h
. If you want to expand the project, you can connect up to seven more LM75 chips to the bus given existing inputs.
There is a bridge on the circuit diagram between GIP16 and REST. Refer to the pin on the ESP8266 and not the web service here. This bridge is necessary for the ESP8266 to wake itself up from energy saving mode. The remaining resistors serve to configure the boot loader and activate the WiFi module.
The MCP1700-330 takes care of correctly supplying power to the semi-conductor. It has an extremely limited transverse current (1.6 µA). There is a sufficiently low differential of 178 mV in the current between In and Out. This current regulator was designed precisely for situations like this one, where battery operated circuits temporarily experience high demands for electricity (in this case 250 mA).
The two 1-µF capacitators are to prevent the current regulator from starting to vibrate. Four NiMH batteries provide the power supply. Theoretically, the setup could make do with three batteries but the test system had a holder that accommodated four, so…
The setup includes a reset button. This means you don't have to interrupt the power supply and restart when you want to upload a new program. The Arduino IDE is used for coding these. Tips on installation can be found in Part 1 of this series [4].
The C program (Listing 1) for the ESP8266 has a somewhat unusual structure. The complete program is found in the setup()
module that the program calls only one time. The loop()
function remains empty. This isn't an issue because the ESP8266 puts itself to sleep at the end of the setup()
module.
Listing 1
getTemperature.c
01 #include <Wire.h> 02 #include <ESP8266WiFi.h> 03 04 const char* ssid = "<SSID>"; 05 const char* pass = "<Password>"; 06 const char* serverIp = "192.168.2.2"; 07 const int serverPort = 8080; 08 const int i2caddress = 0x48; 09 const int interval = 5; //sec 10 WiFiClient client; 11 12 int8_t getTemperature() { 13 int8_t high; 14 int8_t low; 15 // LM75 wake up 16 Wire.beginTransmission(i2caddress); 17 Wire.write(01); 18 Wire.write(00); 19 Wire.endTransmission(); 20 delay (1500);// morning grouch 21 Wire.beginTransmission(i2caddress); 22 Wire.write(0); 23 Wire.endTransmission(); 24 Wire.beginTransmission(i2caddress); 25 Wire.requestFrom(i2caddress, 2); 26 if (Wire.available()) { 27 high = Wire.read(); 28 low = Wire.read(); 29 } 30 Wire.endTransmission(); 31 // LM75 go to sleep 32 Wire.beginTransmission(i2caddress); 33 Wire.write(01); 34 Wire.write(01); 35 Wire.endTransmission(); 36 return high; 37 } 38 39 void setup() { 40 int8_t temp; 41 // I2C Setup 42 Wire.begin(4, 5); 43 Wire.setClock(1000); 44 // Serial (USB Monitor) Setup 45 Serial.begin(115200); 46 Serial.println("\r\n") ; 47 //WLAN connect 48 WiFi.begin(ssid, pass); 49 while (WiFi.status() != WL_CONNECTED) 50 { 51 delay(500); 52 Serial.print("."); 53 } 54 Serial.println(""); 55 Serial.print("connected with "); 56 Serial.println(ssid); 57 Serial.print("IP address: "); 58 Serial.println(WiFi.localIP()); 59 // Messen 60 temp = getTemperature(); 61 // Rest Request 62 Serial.println(temp); 63 if ( !client.connect(serverIp, serverPort) ) { 64 Serial.println("connect fail"); 65 } 66 client.print("GET /rest/setTemp/temp/"); 67 client.print(temp); 68 client.println(" HTTP/1.1"); 69 client.print("Host: "); 70 client.println(serverIp); 71 client.println("Connection: close"); 72 client.println(); 73 client.stop(); 74 // ESP8266 put to sleep 75 ESP.deepSleep(interval*1000000); 76 } 77 78 void loop() {}
A hardware reset for GPIO 16 on the REST pin triggers the wake up sequence. The hardware will restart in setup()
. The interval
variable indicates the length of time in seconds that the component goes into energy saving mode. Most of the remaining constants are self-explanatory. The Wifi credentials can be configured with ssid
and pass
. You can specify which computer should run the REST service using serverIp
and serverPort
. The constant I2caddress
incorporates the address of the LM75.
The getTemperature()
module delivers the current temperature measurement from the LM75. Internally, this mode first wakes up the sensor and then waits a moment before asking for a measurement value. The process works this way because the LM75 is truly a grouchy little thing when it comes to waking up and will deliver inaccurate measurements immediately upon coming out of sleep mode. The sensor requires almost two seconds of awake time before it will deliver precise measurements.
After reading out measurement values, the mode puts the LM75 back to sleep. In the interests of simplicity, the application reads values only in whole degrees in Celsius from the LM75. A large part of the program provides debugging information via the USB interface. This includes all of the lines that begin with Serial.
. For the sake of efficiency, you should comment out these lines.
Now return to the start of the program. The first two lines in the setup()
module activate the I2C-Bus. The next line activates the serial interface. The section that comes after these lines initiates the Wifi connection.
Next, the program calls up the getTemperature()
module and transmits the result to the REST server. The ESP8266 then goes back to sleep. Figures 3 and 4 show the change in energy requirements for our assembly once the chip goes into sleep mode. You will find the code for this project on our FTP server at [6].
The basics for the REST service takes a measurement and writes it together with the time of day to the MySQL database. From there you can process it further with the program of your choice.
Some preparatory steps are required for the installation so that the REST server can get up and running on the Raspberry Pi. Due to Java's legendary appetite for resources, it makes sense to turn to a Raspberry Pi 2 or 3.
Pages: 7
Price $15.99
(incl. VAT)