AZ-ONEBoard in MicroPython - Teil 3 - Luftqualität mit SGP30 - AZ-Delivery
This post is also as PDF document available.

In the previous contributions AZ-Onboard with BH1750 and AZ onboard with SHT30 We had dealt with the light intensity sensor BH1750 and the SHT30, which measures temperature and relative humidity. Today the third sensor of the kit is coming, the SGP30. He is responsible for measuring the air quality indoors. The acronym IAQ is derived from this property, Indoor Air Quality. For this sensor we will knit a micropython module.

With the expansion of the AZ outboard from the second episode, we can also control a relay and two LEDs. Three GPIOs still remain free. Using LED and relay, let's take a look at how to switch a switch with a time delay in the program (staircase machine, monoflop) and an input switch with hysteresis, i.e. with a staggered single-out sweat. We also try to build a nice little gadget with the BH1750. Have you ever turned on an LED with a lighter and then simply blown out later? We discuss all of these topics in this new episode from the series

Micropython on the ESP32, ESP8266 and Raspberry Pi Pico

today

The AZ outboard in full expansion

All three satellite boards for the AZ-Eoneboard have the same pin assignment and are therefore interchangeable. The order of the pins on the OLED deviates from it. When connecting to jumpling cables, you have to be careful not to damage the boards. How you can lead the GPIOs unused by the AZ onboard. Is im second part described. For the I2C bus expansion, I cut a small hole grid board with 4 pins width and 12 pins length and provided myself with an angled plug and a angled socket strip at the ends. In between I have soldered two straight, four -pin socket strips. In addition to the three standard sensors, I can also connect other satellites, such as the OLED display. The contacts are connected along.


Figure 1: AZ onboard with sensors, relays and LEDs

Figure 1: AZ onboard with sensors, relays and LEDs

Figure 2: I2C bus expansion board

Figure 2: I2C bus expansion board

The relay lies with the " +" connection to +5V of the AZ-Onboards, "-" goes to GND and the "S" connection is connected to GPIO15. GPIO13 of the AZ-EONboard leads via a 1.0kΩ resistor to the anode of the LED (longer connection), the cathode lies at GND.


Figure 3: Connection of relays and LEDs

Figure 3: Connection of relays and LEDs

The hardware

The usual board with the controller, here an ESP8266, is replaced by the AZ onboard. To the hardware list from the first episode have joined a relay, two resistors and two LEDs. The sensor boards are already included in the kit.

1 AZ-EONboard Developmentboard including Extensionboards SHT30, BH1750 & SGP30
1 0.91 inch OLED I2C Display 128 x 32 pixels
1 1-relay 5V KY-019 module high-level trigger
1 LED green, for example LED light -emitting assortment kit, 350 pieces, 3mm & 5mm, 5 colors - 1x seT
1 LED white
1 Resistance 1.0kΩ for example Resistance resistor kit 525 pieces resistance range, 0 ohm -1m ohm
1 Resistance 150Ω
1 Mini Breadboard 400 PIN with 4 current rails
1 Jumper Wire cable 3 x 40 pcs. 20 cm M2M / F2M / F2F each
optional Logic Analyzer

The software

For flashes and the programming of the controller:

Thonny or

µpycraft

For the first test of the AZ-Onoboard:

Terminal program Putty

Signal tracking:

Saleae Logic 2

Used firmware for an ESP32:

Micropython firmware download

V1.19.1 (2022-06-18).

Used firmware for an ESP8266:

V1.19.1 (2022-06-18).

The micropython programs for the project:

timeout.py: Non-blocking software timer

oled.py: OLED-API

SSD1306.PY: OLED hardware driver

bh1750.py: Hardware driver module

bh1750_test.py: Demo program

bh1750_kal.py: Program for calibrating the Lux values

sht30.py: Hardware driver module

sht30_test.py: Demo program

sgp30.py: Hardware driver module

sgp30_s.py: slimmed down hardware driver module for ESP8266

sgp30_test.py: Demo program

sensortest.py: Demo program

gadget.py: Demo program

Micropython - Language - Modules and Programs

To install Thonny you will find one here detailed instructions (English version). There is also a description of how that Micropython firmware (As of 18.06.2022) on the ESP chip burned becomes. Like you that Raspberry Pi Pico get ready for use, you will find here.

Micropython is an interpreter language. The main difference to the Arduino IDE, where you always flash entire programs, is that you only have to flash the Micropython firmware once on the ESP32 so that the controller understands micropython instructions. You can use Thonny, µpycraft or ESPTOOL.PY. For Thonny I have the process here described.

As soon as the firmware has flashed, you can easily talk to your controller in a dialogue, test individual commands and see the answer immediately without having to compile and transmit an entire program beforehand. That is exactly what bothers me on the Arduino IDE. You simply save an enormous time if you can check simple tests of the syntax and hardware to trying out and refining functions and entire program parts via the command line before knitting a program from it. For this purpose, I always like to create small test programs. As a kind of macro, they summarize recurring commands. Whole applications then develop from such program fragments.

Autostart

If the program is to start autonomously by switching on the controller, copy the program text into a newly created blank tile. Save this file at Main.py in WorkSpace and upload it to the ESP chip. The program starts automatically the next time the reset or switching on.

Test programs

Programs from the current editor window in the Thonny-IDE are started manually via the F5 button. This can be done faster than the mouse click on the start button, or via the menu run. Only the modules used in the program must be in the flash of the ESP32.

In between, Arduino id again?

Should you later use the controller together with the Arduino IDE, just flash the program in the usual way. However, the ESP32/ESP8266 then forgot that it has ever spoken Micropython. Conversely, any espressif chip that contains a compiled program from the Arduino IDE or AT-Firmware or Lua or ... can be easily provided with the micropython firmware. The process is always like here described.

The preparation of the AZ onboard

The board comes with a finished programmed ESP8266. The program demonstrates the possibilities of the three sensors. Figure 4 shows the edition of the program with the terminal program Putty.

Figure 4: Edition with the demosoftware

Figure 4: Edition with the demosoftware

But we want to write and let our own program in Micropython. The first step to the goal is that we burn a corresponding micropython core on the ESP8266 that overwrites the demo program. So first load them Firmware down and then follow of these instructions. The ESP8266 then reports in the Terminal of Thonny:





The SGP30 module

Like the other two sensors, the SGP30 is also controlled and queried by a set of commands. In the BH1750, the bytes were, at the SHT30 it was Words, i.e. 16-bit values. However, the data to be transmitted had the same format. After all, we had to take different times of change in these sensors, but which could be derived from the respective operating mode by calculating or from tables.

With the SGP30 there are also two-byte command discussions, but the feedback on the chip can be 0, 3, 6 or even 9 bytes long. In addition, there are also different delays until the data is available. If you don't want to write your own routine for every command, you have to trick.

We also find two other things that we had already used in the other sensors in this module. This is an exception class that is tailored to the SGP30 class and we also meet the test sum calculation again. For the ESP8266 I also have the module sgp30.py have to shrink healthy because the program for the three sensors was otherwise not to get to run - lack of memory. So here comes the slimmed down version sgp30_s.py.

The SGPerror class

The Exception class SGperror is similar to the construction of the Shterror class from the module sht30.pywhere this was also discussed in detail. I no longer go into this.

In the introduction of the SGP30 class, the import business. pack() from the module struct will help us to change the type. To calculate the absolute moisture of the air in g/l, we need the exponential function ex = exp ().





Then follow a few constants, the device address of the SGP30 is 0x58 = 88 and the polynomial for CRC calculation is 0x131. Care, there is an error in the data sheet, There it says 0x31, that's curd! The start byte for CRC calculation is 0xff and the chip test always delivers the same result 0xD400.





The trick on the commands is simple. Instead of my own routine for every command, I use a bytes object with four elements, which I will break open within the transmission routine. The first two bytes represent the command word that the third byte mentions the number to be received by bytes including the test amount and the fourth byte encodes the waiting time until the data is provided in milliseconds.





The constructor takes a number of arguments. An I2C bus object is mandatory, optionally, different values ​​for the hardware address, as well as for the parameters test and iaq_init be specified.

We pass the reference to the I2C bus object to the corresponding instance attribute and check whether the hardware address is included in the list I2C.Scan() delivers. If the SGP30 is not found, we will throw a SGPboarder Roror Exception. Otherwise we will remember the hardware address. We prove the absolute humidity with 13,355 g/l. This value should be cyclically from the room temperature and the relative humidity (measured with SHT30) using the method rel2abshumidity() to which we will come later.





The serial number is read, as is the version of the feature set. If necessary, we collect a test measurement, the result of which must be 0xD400. We put the data received in Replica In conclusion, we initiate the IAQ measurement.





crctest() calculates the test sum of the received data bytes and delivers True Back if this matches the SGP30 test sum. The chip always sends two data bytes followed by the test sum. The three bytes are on the parameter blobb Give over and first separated in the date of the date and the cheek. The for loops lead the CRC (Cyclic Redundancy Check) through.





Because we also want to send data to the SGP30 with a CRC-byte, we need a routine that calculates the test sum. We hand over the two data bytes and get the CRC-byte back.





The serial number of the chip gets the routine readerial(). We get the numerical value by pushing and or taking the three received bytes. The MSB is the first byte, so it is in Words[0] and so on. The output format is hexadecimal.





The routines for sending comments and receiving the data are here in the method Commandriderresult() summarized. We already know the reason for this, the different length of the data to be received and the deviating waiting times. In addition to the command word, further data can be sent to the SGP30 instead of receiving them. In this case the parameter takes param this as Bytes sequence.





The command word is in the first two bytes of command. If param not None contains, it contains data bytes that must be attached to the command word. We also filter out the number of bytes to be received and the waiting time. Then we write the command and wait delay MS. If now length = 0, no bytes are expected from the SGP30 and we're done.

Otherwise we will pick up the corresponding number of bytes and create an empty list for the data words received.





Because two data bytes and one CRC-byte are read per data word, come length // 3 packages. Each package is subjected to the CRC test. The index I runs from 0 to a maximum of 2 and addresses the slices blobb[0:3], blobb[3: 6] and blobb[6: 9]. If the CRC test was positive, we screw the data word together and add it to the list Words One that we return.

The following six methods now simply use the method Commandriderresult() and back to the command image sequence.





For a reset of the SGP30, General Call Address 0 is sent together with the byte 0x06. All chips that support this feature are reset. This also includes the SHT30.





The SGP30 needs the value of the absolute humidity in grams of water per liter of air for its correct function. With the method set tabsoluteehumidity() The value is sent to the SGP30 in 8.8 fixed point format. We talk about the format even more precisely later. The value consists of a data word (h) that we use by using the method pack() disassemble into two bytes, order Big Endian (>), i.e. MSB first. The method CREATECRC() provides a (1) byte that has to be converted into a bytes object before it blobb can be attached. big stands for Big Endian, which is of no importance in this context, but must be specified because of the syntax. We send the three bytes to the SGP30.





The formula for calculating the absolute moisture is specified in the data sheet. With the help of the SHT30, the input values ​​for temperature and rel. Moisture can be determined.





In abshum the decimal value is stored, as it would come out on a calculator. The SGP30 wants a different format, fixed comma 8.8. This means that the 8 bit of the MSB contain the integer share and the second 8 bits the counter of a break, with the denominator 256 and the value of the second -scale.

Be abshum = 13.355, then 13 = 0x0d is the integer share. We get the decimal abshum % 1, i.e. as a resort of 13.355: 1 = 0.355 or 355 thousandths. We receive the meter of the break with the denominator 256 by multiplying 0.355 with 256, which is 90.88. 90/256 is about 0.355 and 90 = 0x5a is the second byte. Composed, 0x0d5a comes out and is returned. The method wants such a value set tabsoluteehumidity() as an argument.

We can use the decimal value of the absolute moisture abshumidity Call up. The decorator @property allows the call as with a variable, the brackets are eliminated when the call is called.









The query of the measured values ​​for CO2EQU in PPM (parts per million) and tvoc in ppb (parts per trillion (billion)) works in a similar way. The method provides these values Measureiaq() in a list that we access through indices 0 and 1.





There is still no method to convert the decimal value of the moisture into 8.8 format.





If no argument is specified when calling, then we use the value in abshum. If we have calculated a value manually, we can hand it over and to abshum pass on. We calculate the two fixed comma bytes and give back the 8.8 data word.

SGP30 test run

With the program sgp30_test.py we can test the new module. Define import business, bus object and hand over to the constructors of the SGP30 and OLED class.





We use the value for the absolute moisture presented in the constructor, switch it to 8.8 format and send it to the SGP30. In the While loop, we ask the measured values ​​and issue them in Repliad and in the display.

Overall test of all sensors

The Test program It looks similar for all three sensors. Of course, all three classes have to be imported and objects have to be created with it.





We define two PIN objects for the relay and the green LED.





Likewise the two variables for the monoflop, the delay switch. To the method Time-out() we'll get further down.





Finally, we initiate the work mode of the SHT30 and set the absolute moisture as above.





In the loop we read the values ​​and output them on the display.





If the temperature is higher than 25 ° C, we switch on the relay. So that it does not flutter all the time when the temperature fluctuates slightly, we choose a slightly lower value for switching off and thus create a so -called Hysteresis, a switchover delay.





If the illuminance falls below 150 lux, the green LED is to be switched on and stayed for five seconds. We regulate this with the non -blocking timer using the method Time-out(). It gives a reference to the function encapsulated in it compare(), one Closure, back that we the identifier expired assign. The call from expired() delivers True Back when the 5 seconds are up. In the meantime, however, the While loop will continue to be carried out. triggered = True indicates that the LED is already switched on. The block may only be executed if the LED does not yet light up.





If the timer has expired and the LED, it must be switched off. triggered Let's put false again.





We are still waiting for the SHT30 measuring cycle to end and start the next round.

Lit and blow out the LED

As a gag, I had built a circuit with an LDR, a transistor and a light beam as a gag.

Figure 5: lamp gadget

Figure 5: lamp gadget

If you hold a burning match between the light bulb and the LDR, the lamp starts. If you blow the lamp so that it swings to the side, the lamp goes out.

The arrangement can be set up as a digital variant with the AZ-EONboard and the BH1750. The incandescent lamp is replaced by a white LED and the LDR by the BH1750. The ESP8266 takes care of the implementation of the very simple tax program.

Figure 6: Lamp gadget with AZ-Onoboard, BH1750 and LED

Figure 6: Lamp gadget with AZ-Onoboard, BH1750 and LED

We measure a few illuminated strengths in advance. For safety reasons, we do not use an open fire, but a flashlight.

Normal ambient light on the BH1750: 467

With the LED switched on at a distance of 5 cm: 3853

Flashlight at 20cm away: 8310

We are based on these values ​​in program When specifying the limit values.





After the imports we instantiate an I2C bus object again and assign it to the BH1750 constructor. We connect the cathode of the LED to GPIO14 via a resistance, the anode we put on the +5V connection of the AZ onboard. The LED is out when the output is logical 1. The voltage of GPIO14 is now 3.1V and is therefore absolutely in the green. If we put the output on logical 0, the LED lights up. A current of 10.8mA flows, also okay!

The BH1750 works in the Continuous Highthresolution fashion. It therefore needs 120ms break between two measurements. We pick up a value and check for the area.

The value of 3000 ensures that the LED starts with the flashlight when light lighting the BH1750 and remains in order to continue to illuminate the sensor with 3800 lux.

If the LED is deflected far enough from its direction to the BH1750, for example by blowing, the exposure value falls below 1000 and the LED is switched off.

DisplaysEsp-8266Projekte für anfängerSensoren

Lascia un commento

Tutti i commenti vengono moderati prima della pubblicazione