The inspiration for this project stems back to my childhood when I was curious to find out how the mechanical barometer worked.
The Pico Baro V2 features a miniature 180-degree servo motor has been employed to the drive for the indicator, and a Nano power timer has been used to reduce power consumption in-between measurements which I have set to 15-minute intervals.
The program has been written in Micropython for the sake of simplicity and a shorter learning curve, I used Thonny as my IDE.
List of components:
- 1x Raspberry Pi Pico
- 1x SparkFun Nano Power Timer TPL5110 Or 1x Makerverse nano power timer
- 1x Makerverse Protoboard 30 Row
- 1x PiicoDev Expansion Board for Raspberry Pi Pico
- 1x PiicoDev Cable 100mm
- 1x Monk Makes Relay for micro:bit
- 1x PiicoDev Atmospheric Sensor BME280
- An assortment of prototyping wires
- 1x 40 Pin Female Header Strip
- 1x Tower Pro SG90 micro servo or similar servo
- A hot glue gun and glue sticks
- A soldering iron and some solder
- Coloured hookup wire for interconnections
- 1x Quill 5mm PP Signboard 500 x 770mm White (Corflute) from Officeworks
I cut a square piece of 190mm x 190mm x 5mm thick Quill PP Signboard White. Some legs were made by cutting two pieces of the signboard approximately 105mm x 30 mm. 5mm wide slots were cut into the legs so as to be able to glue these to the mainboard.
All solder connections were made on the Makerverse Protoboard to enable interconnections with jumper wires between the individual components. A female header strip was cut to several pins long and soldered on the protoboard for this purpose.
Then the template image was printed and glued to frame (The image can be found in the attachments file).
import array, time, machine from machine import Pin, PWM, ADC import rp2 from PiicoDev_BME280 import PiicoDev_BME280 from time import sleep adc = ADC(Pin(29)) # create ADC object on ADC pin 29 which is internally connected to VSYS via a voltage divider. ADCfactor = 65535 # Full scale reading of ADC input for 3.3volts plus internal voltage divider value. InputVolts = 0 #place holder for reading external volts applied to the VSYS pin of the Pico. BatteryLed = machine.Pin(22, machine.Pin.OUT) # Connected to front panel Red Led to indicate a Battery change is needed. BatteryLed.value(0) # The Led is turned on when the Battery is below approximately 3Volts. led = machine.Pin(25, machine.Pin.OUT) # Default Led on the Pico Board. led.value(1) sleep(2.0) #Allow time for BME280 to initialise. # NB: If this time is not provided, it will cause an exemption to be triggered in the driver for the BME280. # When an exemption occurs, the program cannot proceed. The power timer will not turn off. # Therefore the Pico will remain on and no readings will be displayed until the batteries are dead. powerpin = Pin(15, Pin.OUT, Pin.PULL_DOWN) #logic 1 turns on Solid State Relay powerpin.off() # Power to the servo is initially turned off through the solid state relay. powerdone = Pin(2,Pin.OUT, Pin.PULL_UP) # This pin is used to tell the power timer to turn off. powerdone.off() # When the Pico has finished doing its work then this pin will go into the high state. sleep(1.0) sensor = PiicoDev_BME280() # initialise the Pressure Sensor. PwmFactor = 8500 #-90 deg of servo motor. ServoPos = 8500 # Initial Servo position. pres_disp = 0 PrevPos = 0 # Place holder for the previous Servo position. FilePos = " " # store an empty string initialy. A place holder for the pressdata.txt file value. # Setup Pulse width modulation Pin for output to the servo. pwm0 = PWM(Pin(0)) # create PWM object from a pin for the servo positioning. pwm0.freq(50) # set frequency of modulation. led.value(0) file = open("pressdata.txt", "r") # Read in previous sensor value from text file. FilePos = file.read() file.close() led.value(1) tempC, presPa, humRH = sensor.values() # we are only interested in the presPa value. pres_hPa = presPa / 100 # convert the Pressure reading into a usable number. pres_disp = abs (round (pres_hPa - 1000)) # this gives us a single digit value. if pres_hPa < 1000: # If the pressure reading is less than 1000 hPa then our reading remains a 0 value. pres_disp = 0 if pres_hPa > 1030: # if the pressure reading is higher than 1030 hPa then our reading will remain at 30. pres_disp = 30 ServoPos = PwmFactor - (pres_disp * 215) # A fudge factor for biasing the servo position. pwm0.duty_u16(ServoPos) # Sets the PWM duty cycle and as a result the servo position. led.value(0) if (str(ServoPos)) != FilePos: #Compare the previous pressure value to the current pressure value. led.value(1) file = open("pressdata.txt", "w") # save the new pressure value to the text file if there was a change. file.write(str (ServoPos)) file.flush() file.close() pwm0.duty_u16(ServoPos) # the new servo position to be applied to the servo or duty cycle change. powerpin.on() # turn on the servo. sleep(3.0) # give servo time to reposition 3 seconds to new position. powerpin.off() # turn off the servo. led.value(0) InputVolts = (abs (((adc.read_u16()) / ADCfactor) * 9.66)) # read value, 0-65535 across voltage range 0.0v - 3.3v if (InputVolts) > 3: #if battery is more than 3Volts then power off the Pico. powerdone.on() # send done signal to power timer and pico is turned off for a period of time. else: # if battery needs changing remain in loop. This will not power off Pico. sleep(0.1) while True: # The Pico will remain in this loop until the Batteries are dead. print (InputVolts) # prints the Battery volts data out to the usb port if plugged in. BatteryLed.value(1) # Light up front panel Led to indicate that Batteries need changing. sleep(2.0) # Note: The Led can be replaced by a buzzer if desired or a buzzer can be added as well as the Led.
How the program works:
There are some driver files required to be loaded to the pico before the main.py can run(Files can be found in the attachment below or you can download them from the guide page for the BME280).
Make a subdirectory in the Pico file system called lib and place these files in the lib subdirectory.
A text file needs to be created (pressdata.txt) and added to the Pico with an initial single value of 8500.
When the power is first applied, a two-second plus 1-second(3 delay is required for the BME280 to initialise before the driver is called. Then a reading is taken from the BME 280. The pressdata.txt file is then opened and the value in the txt file is then compared to the sensor value.
If these values are different, the old value in the txt file is overwritten by the new value from the sensor reading.
Straight afterward the new data is used as the position for the servo motor and then the solid state relay is turned on through pin 15 of the Pico.
The servo motor is then only turned on and repositioned when the Barometric pressure reading changes by 1 full hPa, thereby conserving battery power.
The pwm output has been segmented into 30 different positions in which each position is equivalent to 1 full hPa of pressure difference. So the full range of the servo (180 degrees) is divided into 30 segments.
The time taken for the servo motor to be repositioned is dependent upon how far it needs to travel and the voltage applied to it.
I estimated a value of about 3 seconds for the on time should be sufficient. After this the solid state relay is turned off.
Just before the Pico code sends a “done” signal to the Nano power timer’s (done) input pin, the battery level is checked. If the battery level is below the user-set level, in this case, 3 volts then the Pico will turn on the “Change battery Led” and enter into a loop. In the low battery state the Change battery Led will remain on, reminding you to charge the batteries or replace them and the Pico will remain in the loop until the batteries are dead or swapped.
If the batteries are above 3 volts the entire system is powered down. Only the timer in the Nano power timer is running which draws only a few micro amps.
The program cycle then repeats over again when the power is reinstated by the power timer.
I set the dip switches on the Nano Power Timer to set a time of 15 minute intervals between on times.
The pressure range that can be displayed has been limited to 1000 hPa to 1030 hPa. A measurement outside this range will not move the servo motor beyond its limited range of 180 degrees.