|
Post by lbendlin on Feb 5, 2019 14:18:59 GMT -8
Project overviewThe aim is to create an autonomous edge computing device that can measure environmental parameters (temperature, humidity, pressure), take pictures and video (day and night), operate a coop door and a heating lamp, and generally serve as a testing ground for various ideas. Setup: waterproof utility box. Side holes covered with silicone, bottom holes left open for pressure balance and ventilation (may need to add fan later for better circulation) Sturdy aluminum tetrahedron as base for solar panel holder and tracker. Manual adjustment of axis inclination (planned once per season, or maybe not needed at all) by using different hole combinations in the tetrahedron. Note the use of naturally occurring materials (ie stones) for weighing the setup down. It is susceptible to very heavy winds that we seem to be getting more frequently, but holds on fine otherwise. Servo to move solar panels (2x6W) around tilt axis (currently MG996R with rain cover, but looking into using a waterproof servo instead) _ Separate 300mW panel to recharge the servo battery. Can easily be replaced by a 100mW panel, even when actuating servo every five minutes during daylight. So far the box houses (counterclockwise): - 10000 mAh LiIon battery with thermistor under it - SunControl board - Solar panel combination board (to prevent cross currents between panels) - Quad Power Management board to control the individual solar panels - 6 port I2C hub - BME280 for internal temperature, humidity, and pressure - 4400 mAh battery for servo circuit - Adafruit solar battery charger - INA219 Voltage/current measurement (to decide if the servo battery needs charging) - Adafruit voltage booster/power control (raises servo voltage to 5.2V and only enables servo for movement) - Raspberry Pi Zero W with PaPiRuS ePaper HAT (including RTC and LM75B temperature sensor) - Pi camera (currently fixed, to be mounted on servo turret later) - 10W 6.2V Zener diode with heatsink to make sure Suncontrol board doesn't get overwhelmed by idle voltage of solar panels) Outside the box are the solar panels and an AM2315 temperature/humidity sensor. I had to position that far away from the box as the heat radiated from the grey box is more than enough to skew the AM2315 readings.
|
|
|
Post by lbendlin on Feb 5, 2019 14:33:29 GMT -8
General purpose
The idea is to make the device last as long as possible. That means monitoring and trying to minimize consumption, and maximize energy generation and storage
monitoring: INA3221 and INA219 for checking the vitals of the SunControl board, the batteries, and the solar panels. Since the system is autonomous I can assume that all incoming energy (from the panels) is fully consumed by the load, the battery, and the Suncontrol board. There are big differences in the energy being thrown away (converted to heat) in various scenarios. About 3% loss without solar charging, up to 75% loss with full sun (ie only 25% of the solar power actually ends up in the battery)
minimize consumption: Disabling all unneeded components on the Raspberry Pi (HDMI port, status LEDs). Using USB control circuit (controlled via GPIO from Raspberry Pi) to provide power to the servo only when the servo is asked to move (once every five minutes). I also checked the idle amperage of all the I2C devices to see if I should switch some off when not needed but they are all in the microampere range, so not worth the effort. Current load power consumption is about 580mW, I'm happy about that. I plan to replace the Pi Zero W with a Pi A or A+, and use LORA transceivers instead of WiFi, that should bring it down another 100mW
maximize generation: adjustment of solar panels as needed. I chose not to use a sun tracker, and instead went for a software solution. The PySolar library takes a location and datetime and provides the elevation and azimuth of the sun for that data set. My tetrahedron limits the solar panel movement from 60 degrees (east) to -60 degrees (west) of noon. Also the trees around the location and the general topography limit the usable elevation to above 7 degrees. During the day I check if these limits are met, and move the panels to the sun every five minutes. Once the sun dips below 7 degrees I pre-rotate the panels back to 20 degrees so the whole setup can potentially recover from a battery cutoff.
|
|
|
Post by lbendlin on Feb 5, 2019 14:42:41 GMT -8
Results so far
We had an exceptionally cold winter so far, putting a real strain on the LiIon batteries. Battery capacity was much lower than under normal temperatures, and a combination of operator error (using both thermistor and 10K SMD resistor) and weird SunControl board behavior (tends to switch the output off in the cold, rather than the charging circuit) have not yet allowed me to come to a stable situation.
The battery easily lasts through one night when close to full but won't be able to brigde two nights if there's not enough sun in between. Measuring battery levels proved to be quite tricky. When the solar panels provide power this also pushes the battery voltage as measured by the INA3221 up substantially. As a workaround I now switch the solar panels off (via the QPM), take my battery reading, and then switch the panels back on. That should give me a much more realistic reading, but I don't know if the interruptions in the charge process will adversely affect the battery.
I am tempted to add a second battery (or use a larger one) but I think that will adversely affect the hysteresis circuit on the SunControl board, as it will then take twice as long to get the battery bank to the "switch load on" point in the hysteresis loop. Since the goal is for maximum availability I want to provide power to the output as soon as there is just enough juice in the battery - especially when that is early in the morning and there's a good chance for some additional charge.
The charge limit of 1A will likely also play a role. Even with more battery it will limit daily production to not much more than 7Wh.
The QPM keeps disappearing from the I2C bus, preventing me from reliably controlling the switches. I suspect this is caused by overvoltage on the I2C supply (which comes from the Raspberry Pi via the USB output of SunControl). Seems to work fine below 5.3V but not above 5.4V. Short term remedy was a 5.1V Zener diode across the USB output of the SunControl, but that increased the idle wattage substantially (from 580mW to 840mW !) so right now I selectively switch off one of the solar panels if the output voltage is above 5.3V
The solar panels can deliver a combined 7W with current winter sun levels, might be a bit better in summer. Not bad so far, but seems to overwhelm the SunControl charge circuit at times - that is limited to 1A charge current. It's a conundrum - during overcast days you'd need four panels or more but at full summer sun even one panel is too much. Worst case I need to turn the panels away from the sun just enough as not to exceed the 1A limit.
The servo circuit is now rock solid (after many many futile approaches - note: integer arithmetic is no good for servo fine control ), the solar panel and battery for the servo are totally oversized and can easily be replaced by much smaller values. The important part is the servo voltage (5.2V is much better than 5.0V) and the ability of the voltage booster to deliver up to 1A when (briefly) needed by the servo.
I still need to validate that the thermistors works as advertised, cutting off the charging circuit in adverse temperatures (but not the output circuit!)
Since the solar panels are controlled by the QPM I do currently rely on the SunControl to supply power to the QPM even after the SunControl has shut down the output to the Raspberry Pi. That means when the hysteresis cutoff occurs the SunControl panel still needs to stay powered on at least until the next availability of solar energy.
On the QPM I have shorted the SJ1 and SJ2 bridges that will make sure the solar energy reaches the SunControl board. I haven't yet have to deal with a totally dead battery or other freak corner cases.
|
|
|
Post by lbendlin on Feb 5, 2019 14:55:28 GMT -8
Future plans
- Implement proper shutdown and wakeup procedures for the output load and make sure the QPM does not adversely affect the startup of the entire system from scratch/dead battery. Thinking of using the RTC on the PaPiRus HAT (which has its own buffer battery) for scheduled wakeup attempts
- Use Peltier elements for heating the box in winter and cooling it in summer. Power the Peltiers once there's sufficient charge in the main battery, or maybe power them from the servo battery.
- Add a 5V fan for forced ventilation of the box (inside the grey box it reaches 85F air temperature with full sun even at around freezing outside temps)
- Add pan/tilt servos to the Pi Camera and a dome. Maybe add controllable IR lights for night pictures.
- Use a second SunControl board to replace the three individual boards for the servo circuit
- Add another I2C hub and control its power via QPM (in case any of the i2c devices consume too much while idle. Not really needed at the moment)
- Add an I2C rotary encoder for reading back the actual position of the solar panels. Sometimes the servo is too lazy to actually move the panels as directed.
- Use a second QPM for more cowbell (don't really need it but it is a cool board - the only Solid State Switch board on the market with independent power per switch - other boards have common rails).
- Add stuff to control the chicken coop door, the feeders, monitor the nesting boxes, do face recognition/roll call etc.
|
|
|
Post by SDL on Feb 6, 2019 17:58:10 GMT -8
Lutz,
What an incredible writeup!
You are rocking and rolling. John tells me that in his CS452 RTOS (Real Time Operating Systems) and IOT devices, two of his students gave presentations of IOT versions of Chicken coops. They were especially interested in using RFID or video to identify individual chickens so they could track production.
BP
|
|
|
Post by lbendlin on Feb 9, 2019 15:35:38 GMT -8
Some of the biggest challenges with chicken IoT are the chickens. They have no respect for technology, and despite repeated warnings have destroyed many a ribbon cable that wasn't tucked away good enough. I cannot see how you would be able to attach RFID tags to them unless you can wrap the tag around a leg. And don't get me started on nesting boxes. There is absolutely no rhyme or reason to their decision process as to which box to use (except maybe pure nastiness). I have had cases where a chicken chose a nesting box that was already occupied by another chicken! Yep she just laid the egg on top of her colleague. Which reminds me - need to search for I2C enabled weight strips - something like this github.com/simlun/i2c-weight-scale
|
|
|
Post by SDL on Feb 10, 2019 10:42:17 GMT -8
Lutz,
You are just a hoot. Or a cluck. This is a great project.
John Shovic
|
|
|
Post by lbendlin on Feb 12, 2019 20:09:14 GMT -8
Update: replaced all Adafruit boards with a single SunControl board. I was about to add another QPM as well but then I looked at the consumption and each QPM uses 8mA. I don't think I want to spend that kind of energy for an idle board just yet. I also changed the power supply for the i2C bus to the secondary circuit (had to remove the power in from the I2C connector coming from the Raspberry Pi that was originally providing I2C bus power). and in the process learned that the devices on my I2C bus consume 14mA. Need to chase down what the offenders are (besides the remaining QPM board) Lastly I rewired the USB output control on the new SunControl board to recreate the original servo power control. I could have used the GPIOs on the QPM for that but for now the simple rewire works just fine.
|
|
|
Post by SDL on Feb 13, 2019 13:58:26 GMT -8
Lutz,
To reduce the current for the QPMB boards, pop off all 5 of the LEDs. It will drop to almost nothing.
You do nice work!
BP
|
|
|
Post by lbendlin on Feb 13, 2019 17:07:15 GMT -8
I checked, and the red LEDs on the QPM consume 2.3 mA each. I don't really want to pop them off as they are good for troubleshooting. But what I could do is set the switches to off overnight when the solar panels are idle. Problem is that I need the solar panels to be on and ready in the morning, even when the main load (Raspberry Pi) is off due to its battery being depleted.
My secondary power circuit now has an 8000mAh battery and even with the LEDs on I am looking at 20 mA constant load when the servo isn't running. I guess I'll just bite my tongue on that.
|
|
|
Post by lbendlin on Feb 22, 2019 16:34:25 GMT -8
The 5.6V 10W Zener diode is now in place across the solar panels, and worked well on a very slightly overcast day - no more overvoltage. Max battery charging current is at 945 mA - hope I can see a little higher than that with full sun. The light green line is the reported battery voltage while charging, and the dark green line is the actual level (I briefly disconnect the solar panels and take a second measurement if there is more than 100 mA coming from the panels) w = waste (energy consumed by the SunControl board) o = energy sent to the output
|
|
|
Post by SDL on Feb 24, 2019 17:33:29 GMT -8
Ohhhhmmmm. Lutz, this is great. I'm looking at what to do about this problem long term. John got his Project Curacao box back from the Caribbean on Thursday. It had quit. I thought it was this problem, but it wasn't The WatchDog timer was disconnected and it got into the shutdown state and then the voltage recovered and it never booted again. So, everything was fine, except for the watchdog timer. BP Attachments:
|
|
|
Post by lbendlin on Feb 25, 2019 5:07:03 GMT -8
I am thinking RTC . The Papirus hat has a RTC with a trigger pin, (https://github.com/PiSupply/PaPiRus/tree/master/hardware/PaPiRus%20HAT) but I haven't figured out yet if that can be done repeatedly, or if you can only do one alarm at a time.
The trigger pin could override the Grove USB control somehow (conveniently it briefly pulls to GND upon triggering). I think philosophically the RTC is something like a lazy watchdog (watchsloth?) that can work on larger timescales.
On the Pi I could set the RTC alarm for "x hours from now". Then after five minutes I would cancel the alarm and reset it for same "x hours from now". If the setup freezes at any time the alarm would power cycle (or at least power down) the output, and the output could then recover either immediately or when the battery is charged again.
The RTC trigger pin would have to be connected to both USB Enable and USB Control for this to work (sort of as an electronic latching relay). Any concerns with that?
|
|
|
Post by SDL on Feb 25, 2019 8:57:17 GMT -8
That sounds like a good idea. We have used our DS3231 RTC for similar purposes, but found it would quit after a month or so.
I see the PaPIRus hat is using a MCP7940 RTC but I don't have any experience with that chip.
BP
|
|
|
Post by lbendlin on Feb 26, 2019 6:48:09 GMT -8
I worked on improving the solar cell management. Goal is to switch on as many solar cells as possible without violating the boundaries set by the battery temperature and the solar cell voltage range. This includes the scenario where it is too cold/hot to charge the battery but still ok to contribute to the output power.
Here's the base decider:
def solarOK(batterycurrent,batteryvoltage,temperature): # good temperature range? if (mintemp < temperature < maxtemp): #is the battery already full? if (batteryvoltage > maxbatteryvolt): return False else: return True # only enable if not charging else: if(batterycurrent <0.0): return False else: return True
And then I use that decider to gradually try each individual panel (I use three):
# switch panels back on based on charging current and battery temperature. QuadPower.setPowerChannel(4,QuadPower.QuadPower_ON) time.sleep(0.2) if solarOK(ina3221.getCurrent_mA(1),ina3221.getBusVoltage_V(1),t): #switch on first large panel QuadPower.setPowerChannel(2,QuadPower.QuadPower_ON) time.sleep(0.2) if solarOK(ina3221.getCurrent_mA(1),ina3221.getBusVoltage_V(1),t): #switch on second large panel QuadPower.setPowerChannel(1,QuadPower.QuadPower_ON) time.sleep(0.2) if not solarOK(ina3221.getCurrent_mA(1),ina3221.getBusVoltage_V(1),t): QuadPower.setPowerChannel(1,QuadPower.QuadPower_OFF) else: QuadPower.setPowerChannel(2,QuadPower.QuadPower_OFF) else: QuadPower.setPowerChannel(4,QuadPower.QuadPower_OFF)
This seems to work nicely as shown in this chart. There are a few attempts at 7am and 8:30am but only the smallest panel is producing power that stays within the envelope (in this case no charging is permitted as the battery temperature is too low). Then at 9:30am the battery temperature is finally high enough (because the sun hits the weatherproof box) and it's go on all engines, for a maximum charging current.
A downside of this approach is that I run the decider every five minutes. This means switching all panels off and then selectively switching them on again. No idea what impact this has on the QPM or on the charging circuit. It also means I am missing any big events happening inside the five minutes (like fast moving clouds) and could expose the battery to a potential charge event when it shouldn't be charged. I am not yet ready to increase the monitoring frequency - will see how stable this setup is.
|
|