Blog


MySensors Solar Powered Node – Part 3

There’s been a bit of gap since my last post. Two items have been particularly problematic. Firstly, accurately determining the battery voltage and secondly getting around the low power startup failure.

I got a bit sidetracked. I tried to use a Thyrsitor to switch current on/off to the MCP1703. This was triggered by the voltage from the Supercapacitor. This doesn’t work!

A Supercapacitor doesn’t behave like a battery. Once current is drawn, there is an immediate voltage drop. My Thyristor testing showed that this simply caused a on/off/on/off…. sequence to occur. As soon as the thyristor switched on the voltage dropped, the gate on the thyristor closed and power was cut. At low light levels the power from the solar panel just isn’t enough to stop the voltage from dropping.

I managed to get around the Thyristor problem by using the Arduino to determine when to draw power. More on this later on.

Getting the Maximum Solar Voltage

I want the supercapacitor to charge as quickly as possible. In order to do this the open supply voltage from the solar panel needs to be as close to 5.5v as possible. It occurred to me that the diode that I first chose was not very clever. It has a 0.7v voltage drop for most of the time. A 0.7v drop at low light levels is significant. It can be the difference between the circuit switching on or off.

I replaced the existing diode with a STMicroelectronics BAT43, Schottky Diode, 30V 200mA. This has a peak forward voltage drop of 450mV.

This will be obvious to a lot of fokes. Not to me!

Protecting the Supercapacitor

As the voltage drop with the above diode is now much smaller it is possible the solar voltage could rise above 5.5v. I used a zener diode to clamp the voltage across the Supercapacitor to 5.6v. This should be 5.5v but I couldn’t source a component. Zener diodes do nothing until the voltage rises above their rated value and then they start conducting (backwards…).

Low Voltage Start

This was a big, big problem. I’ve explained how my thyristor solution didn’t work. I went back to trying without the thyristor. It still didn’t work! As soon as there is enough power for the Arduino to start, the MySensors library switches on the radio and tries to ‘present’ the node. This is power hungry, too much current is drawn and the radio initiation fails. The MySensors library then goes into startup loop until the supercapacitor is dead.

I got around this by modifying my sketch. In the event that the start voltage is too low I power down the radio and then sleep. This works!

Here’s an example of the hackery I added to the MySensors before statement to power down the radio if the voltage isn’t high enough.

void before()
{ 
  analogReference(INTERNAL) ;
  
  for (;;) {  
   int sensorValue = analogRead(BATTERY_SENSE_PIN);
   sensorValue = analogRead(BATTERY_SENSE_PIN);
   float batteryPcnt = static_cast<float>(static_cast<int>(sensorValue*10.0 / 10.23))/10.0;
   int batteryV = static_cast<int> ( batteryPcnt*55);

   if (batteryV> ON_BATTERY_VOLTAGE) 
    break;
           
    transportInit();
    transportPowerDown();
    hwSleep(CHARGE_SLEEP_TIME);
   
    if (preHwInit) {
      preHwInit();
    }
    hwInit();
   }
}

Measuring Voltage using Arduino

Should be easy right? All we have to do is attach a voltage divider to one of the analogue pins. We know that the maximum input voltage should be 5.5v. all  we need to do is select the resistances so that the tax point is 1.1 volts. We’ll obviously use the Arduino internal reference as we can’t rely on the VCC voltage on the Arduino.

I’ve had some odd results. I chose R1 = 1.5M and R2 = 0.377M (47K + 330K). One of my test Arduinos works fine the other systematically reports lower than expected voltages at the tap point. I have no idea why.




MySensors Solar Powered Node – Part 2

I prototyped my Solar Powered Arduino design and started taking some measurements. I’ll show the (really bad) performance of my cheap solar panel, give you an idea of how much current my Arduino and MCP1703 suck and then explain my first stab at a sketch. Remember, this is work in progress and if you read the next post about my Solar Powered Arduino you’ll find out that I came across a few problems that I had to get around.

Solar Powered Arduino – some baselines

Solar Panel

Panel is rated at 6v 150mA ~ 1W. Here are some readings from the panel this morning. It’s a very cloudy midwinter day here. You can see that the panel is <1% efficient at times.

[table caption=”Measured Solar Panel Output” width=” colalign=”left|left|center|left|right”]

conditions, voltage (mV), current (mA)

Very cloudy midwinter 8.30am, 4.2, 0.510

Very cloudy midwinter 10.00am, 5.0, 0.810

Very cloudy midwinter 10.30am, 5.63, 1.9

Very cloudy midwinter 12.30am, 5.02, 0.8
[/table]

Arduino

This is a 3.3v Arduino clone with a couple of minor modifications.  The Power LED is removed, the onboard regulator is removed. These are the standard hacks to reduce the board’s power consumption. The bootloader is not modified as we are using the MCP1703 regulator.

It has a standard nRF24L01+ clone attached to it and is running the MySensors 2.1.0 software stack. Here’s an idea of power consumption in different scenarios. These are tested using my cheap multimeter so the uA value is probably not quite right. They are also tested before the MCP1703 as I want to get an idea of total power consumption.

[table caption=”Measured Arduino Power Consumption” width=” colalign=”left|left|center|left|right”]

Arduino, Radio, current (mA)

Awake, On, 30

Arduino Standard Sleep, Off, 4

MySensors Sleep, Off, 0.0077

[/table]

The Solar Panel

It’s worth mentioning this part of the system. I’ve got a few worries here. I ordered a 1N4148TR diode. This is a very cheap low current device (max 300mA), double the rated output of the solar panel. The plan was that the diode was used to stop leakage from the capacitor back through the solar panel when it’s dark. It is also used to drop the voltage from the solar panel to ‘below’ the rated value of the Super Capacitor.

I think I’ve chosen the wrong diode. After measuring the voltage drop with no load, it appears to be just under 0.5v – not enough! As the current increases the voltage drop increases to 0.7v. Ideally I need to find one with a min voltage drop of 0.6v, or work on another solution. This is an interesting post about the 4148 diode characteristics.

I think what the article is telling me is that my diode has a bigger voltage drop at lower voltages and currents. I need either a diode with a fixed minimum voltage drop or a clamping circuit like this to make sure I keep within my voltage limits.

The Sketch

Here’s the example sketch for the Solar Powered Arduino. There are some things to note. If the Capacitor is in a good state then values for battery percentage and voltage are sent to the server every 5 minutes. In the case where the battery voltage has dropped too low, no values are sent and the Arduino sleeps for 15 minutes before checking again.

// Enable debug prints to serial monitor
#define MY_DEBUG 

// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RF24_PA_LEVEL RF24_PA_LOW

#define MY_NODE_ID 98
//#define MY_PARENT_NODE_ID 0
//#define MY_PARENT_NODE_IS_STATIC

#include <MySensors.h>
#include <SPI.h>

#define OFF_BATTERY_VOLTAGE 3500
#define ON_BATTERY_VOLTAGE 3800

int BATTERY_SENSE_PIN = A0;         // select the input pin for the battery sense point
unsigned long UPDATE_SLEEP_TIME = 300000;  // sleep time between reads (seconds * 1000 milliseconds)
unsigned long CHARGE_SLEEP_TIME = 900000;

MyMessage msg(0,V_VOLTAGE);

void before()
{
  #ifdef MY_DEBUG
   Serial.println("Node STARTING ");
   #endif
}

void presentation() { 
  // Send the sketch version information to the gateway and Controller
  sendSketchInfo("Solar board", "1.1"); 
}

void loop()     
{     
   // get the battery Voltage
   int sensorValue = analogRead(BATTERY_SENSE_PIN);
   
   float batteryPcnt = static_cast<float>(static_cast<int>(sensorValue*10.0 / 10.23))/10.0;
   int batteryV = static_cast<int> ( batteryPcnt*50);

#ifdef MY_DEBUG
    Serial.print("Voltage: ");
    Serial.println(batteryV);
#endif
     
   if (batteryV< OFF_BATTERY_VOLTAGE ) {
#ifdef MY_DEBUG
      Serial.println("Voltage POOR - SLEEPING");
#endif
     sleep(CHARGE_SLEEP_TIME);
     return;
    }

   sendBatteryLevel(batteryPcnt);    
   msg.setType(V_VOLTAGE);
   send(msg.setSensor(0).set(batteryV));

#ifdef MY_DEBUG
   Serial.print("Battery Voltage: ");
   Serial.print(batteryV);
   Serial.println(" V");

   Serial.print("Battery percent: ");
   Serial.print(batteryPcnt);
   Serial.println(" %");
#endif
   sleep(UPDATE_SLEEP_TIME);
}

Problems!

My Solar Powered Arduino with the sketch and circuit above does work – mostly. During light periods the Super Capacitor is charged as you would expect. During low light periods the voltage across the Solar Panel drops and the diode stops the panel acting like a resistor.

Voltage Clamping

As mentioned before the voltage drop across the diode is not enough to protect the Super Capacitor. I think that this problem can be solved by voltage clamping the solar panel using a zener diode. This would also allow panels of higher voltages to be used.

MCP1703 should be MCP1700

If a voltage of less than 6v is used after the diode then a MCP1700 would be better suited. This has better performance at lower voltages and wastes less power.

Cheap Super Capacitor

I bought my Super Capacitor from eBay for about £3.50. I’ve eventually found some information on it’s performance (I think). I’m going to test but I think that it has pretty poor performance. It leaks quite a bit. I’ll have to work out how to test this and detail some more results

Low Voltage Problems

This is a problem. When it’s dark and the Super Capacitor voltage has dropped below the threshold required to run the circuit, the system never recovers. The Super Capacitor sits at a voltage of about 1.6v and never charges.

My assumption is that at this voltage the Arduino starts to continuously suck power (even though it is not starting) over the amount that the solar panel can provide. A scenario of starting….failing….starting….failing…starting occurs and keeps the Super Capacitor from charging.

I need a solution for this. Any thoughts?




MySensors Solar Powered Node – Part 1

For now, this post is going to contain a few notes regarding a solar powered MySensors node that I put together last weekend. This may not work, so the post will contain a basic circuit and readings from the setup over the next couple of weeks.

Basic Idea

Hooking together Solar (PV) Panel + Supercapacitor + MCU1703 + Arduino

The idea is to power a MySensors node (Arduino Mini Pro with NRF24L01+ radio) using a small solar panel. A Supercapacitor will be used in place of a rechargeable battery. The Solar Panel and Supercapacitor must be carefully balanced as voltage into the Supercapitor shouldn’t exceed the rated value.

The circuit will include a really basic resistor divider so that the arduino can measure the input voltage to the regulator. The sketch is setup to send back the voltage on the AO pin every 5 mins (more about this later). Here is a basic rundown of the parts:

Solar (PV) Panel: 6v 1W rating, 8cm x 5cm, v.cheap!

Supercapacitor: 5.5v rating, 4F.

Regulator MCP1703: Converts input voltage to regulated 3.3v output. Uses only 2uA (micro amps) when there is no load!

Resistor Divider: Simple resistor divider using spare 100K resistors. Converts 5.3v to 3.3v. Sensed on A0 pin on Arduino

Arduino Mini Pro 3.3v: Arduino Mini Pro with Connected NRF24L01+ radio. Running 2.1.0 MySensors code. Radio links to my gateway which pushes messages to MQTT broker and then this blog using MqttCogs

It’s midwinter here. Very cloudy, no sun and lots of rain. Ideal time to check out a solar panel powered Ardiuno!

Prototype

….and this is what it looks like. All pushed together on a breadboard.


Here’s a list of questions that I want answered over the next few days/weeks.

  • Solar Panel voltage after diode must be less than rating for Supercapacitor. Need to check voltage drop across diode when no current is drawn
  • Need to check Arduino current draw with radio on, radio off and when sleeping
  • Need to check Solar Panel current and voltage in different conditions
  • Need to record how quickly Super Capacitor discharges when no solar panel attached
  • Need to record charging rate of Super Capacitor in different conditions
  • Need to test behaviour of system when Super Capacitor is unable to drive the Arduino properly

 

Live Super Capacitor Voltage

Here’s a couple of graphs using MqttCogs. The first shows the Super Capacitor voltage in the last 2.4 hours, the second the voltage in the last 24 hours.

[mqttcogs_drawgoogle options="{series: {0:{labelInLegend: 'Capacitor Voltage(mV)'}}, animation:{startup:true,duration:5},curveType:'function',title:'(98) Supercap voltage mV (last 2 hours)',height:200, hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' }, vAxis: { title: 'Voltage (mv)' }}" charttype="LineChart" ]]
[[mqttcogs_data from="-0.2"  limit="999" topics="mysensors_out/98/0/1/0/38"/]][[/mqttcogs_drawgoogle]

[mqttcogs_drawgoogle options="{series: {0:{labelInLegend: 'Capacitor Voltage(mV)'}}, animation:{startup:true,duration:5},curveType:'function',title:'(98) Supercap voltage mV (last 24 hrs)',height:200, hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' }, vAxis: { title: 'Voltage (mv)' }}" charttype="LineChart" ]][ [mqttcogs_data from="-1"  limit="999" topics="mysensors_out/98/0/1/0/38"/]][[/mqttcogs_drawgoogle]



How does archiving work?

  • January 5, 2017
  • FAQs

I’m not a very complicated person and nor is mqttcogs. Data from the mqtt broker is persisted into a single database table. Structure includes an id, topic, utc and payload. That’s pretty much it.

Obviously overtime this table can fill up with data and use up your expensive disc space. Mqtt cogs comes with a very basic setting to allow you to remove data from this table.

You simply choose whether to keep all data or a certain number of days worth of data.

Data is removed twice daily. If you want data to be removed immediately you can deactivate and then activate mqttcogs. This will cause the data pruning to occur immediately.




Just get me the last value!

Updated for version 2.3 – mqttcogs_get shortcode is deprecated and replaced with the mqttcogs_drawhtml shortcode

There are instances where a graph might not be appropriate. I might simply want to display the current temperature outside. I don’t want any fancy formatting I simply want to embed the value in one of my posts. Which value though? The temperature is only meaningful if you know the date and time at which the reading was taken.

It is possible to display both using the [ mqttcogs_drawhtml ] shortcode. In it’s most basic form it will return the most recent datetime or payload field. Here’s the code to display the text above:

[ mqttcogs_drawhtml topics='mysensors_out/92/2/1/0/0'] Last known temperature reading is {0,1}C  taken at {0,0}[/mqttcogs_drawhtml]

So my {0,1} corresponds to row 0, column 1 (19.6) and {0,0} to row 0, column 0 (2020-03-20 12:21:11)

How about MIN/MAX for today?

Technically this should work but for some reason it currently isn’t. I’m looking into now. I tried the following but the date isn’t formatted correctly. Watch this space…

[ mqttcogs_drawhtml topics='mysensors_out/92/2/1/0/0,mysensors_out/92/2/1/0/0' group='DAY' aggregations='MIN,MAX' ] Min Temperature today was {0,1}C  taken at {0,0}
 Max Temperature today was {1,2}C  taken at {1,0}[/mqttcogs_drawhtml]

What about other days?

It’s also possible to specify a ‘from’ and ‘to’ attribute and a sort attribute. This would allow you to get the start and end temperature for a given date range. I’m not sure why you might want to do this!




Roadmap or something…

  • December 28, 2016
  • FAQs

Hmm, don’t like the word roadmap. Sounds a bit management. Thought I’d jot down a few ideas about what it might be possible to implement for mqttcogs. The bottom line is that i want to easily be able to visualize ‘data’ on my blog. Data from all different types of sources. It would also be nice if I could update selected data as well…

I’ve moved the content of this page to github. See here




Outside

This sensor is shoved into the ground in my vegetable bed. It’s actually quite useful. Come spring I’ll know when the soil has warmed up enough to start planting my summer seeds. I also like the way the soil temperature lags behind the air temperature. Obvious, but interesting to watch!

 




My Umbrella Plant

This page is devoted to my Umbrella Plant. I don’t love my Umbrella Plant as much as my Basil. It has some flaws. It’s not edible and it doesn’t really grow fast. It also collects a lot of dust. It also appears to be able to tolerate large periods of drought as i’m not very good at watering it.

[ mqttcogs_drawgoogle options="{
  series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
  animation:{startup:true,duration:5},
  curveType:'function',
  title:'(8) Umbrella Plant Temperature',
  height:300,
  hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
  vAxis: { title: 'Temp (F)' }}" 
  charttype="LineChart" ]
          [ mqttcogs_data limit="100" topics="mysensors_out/8/1/1/0/0,mysensors_out/8/2/1/0/0"]
 [/mqttcogs_drawgoogle]

[ mqttcogs_drawgoogle options="
 {series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
 animation:{startup:true,duration:5},
 curveType:'function',
 title:'(8) Umbrella Plant Moisture',
 height:300,
 hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
 vAxis: { title: 'Moisture' }}"
 charttype="LineChart"]
                [ mqttcogs_data limit="100" topics="mysensors_out/8/0/1/0/37"]
 [/mqttcogs_drawgoogle]

 




My Basil

This page is entirely devoted to my Basil plant.  The plant sits on my kitchen windowsill and is south facing. I love my Basil plant. I use it for Pizza and Tomato sauces. It has very green leaves and smells fantastic. It’s not growing very fast at the moment as it’s winter and we are only getting about 8 hours of light.

[ mqttcogs_drawgoogle 
	options="{
				series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
				animation:{startup:true,duration:5},
				curveType:'function',
				title:'(92) My Kitchen Basil Temperature',
				height:300,
				hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
				vAxis: { title: 'Temp (C)' }}"]

	[ mqttcogs_data limit="9999" topics="mysensors_out/92/1/1/0/0,mysensors_out/92/2/1/0/0"]
[/mqttcogs_drawgoogle]

Here’s another graph that shows moisture. The moisture is measured by a capacitive sensor. The units are arbitrary. This is work in progress!

[ mqttcogs_drawgoogle 
	options="{   
			series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
			animation:{startup:true,duration:5},
			curveType:'function',
			title:'(100) My Kitchen Basil Moisture',
			height:300,
			hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
			vAxis: { title: 'Moisture' }}"]
	[ mqttcogs_data limit="100" topics="mysensors_out/92/0/1/0/37"]
[/mqttcogs_drawgoogle]



Multiple Series

The Really Simple example showed how to create simple LineChart and show one series. It’s possible to show multiple series on the same graph. In this example I’m going to show the air temperature and soil temperature for my basil plant that sits on my kitchen window sill. This example shows how to use the topics attribute.

Lets recap. We’ve got a graph on the screen using the following code:

[ mqttcogs_drawgoogle ]
       [ mqttcogs_data topics="mysensors_out/100/1/1/0/0" ]
[ /mqttcogs_drawgoogle ]

Adding another series to the same graph is pretty easy. The topics attribute accepts a comma delimited list of topics. So I can simply change my shortcode to include the second temperature sensor that I have on this probe:

[ mqttcogs_drawgoogle ]
       [ mqttcogs_data topics="mysensors_out/100/1/1/0/0,mysensors_out/100/2/1/0/0" ]
[ /mqttcogs_drawgoogle ]

The output looks like this:

Obviously, we can tidy things up a bit by setting the options attribute as well as described in Labelling Axes. Our shortcode then becomes:

[ mqttcogs_drawgoogle 
	options="{
			series:{0:{labelInLegend: 'Soil'},1:{labelInLegend: 'Air'}},
			curveType:'function',
			title:'(100) My Kitchen Basil Temperature',
			height:300,
			hAxis: {title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
			vAxis: { title: 'Temp (C)' }}" ]
    [ mqttcogs_data limit="100" topics="mysensors_out/100/1/1/0/0,mysensors_out/100/2/1/0/0" ]
[/mqttcogs_drawgoogle ]

The pretty excellent result looks like this: