Blog


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.

Measured Solar Panel Output
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

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.

Measured Arduino Power Consumption
Arduino Radio current (mA)
Awake On 30
Arduino Standard Sleep Off 4
MySensors Sleep Off 0.0077

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!

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.

Last known temperature reading is 17.5C  taken at 2019-09-20 15:07:55

It is possible to display both using the [ mqttcogs_get ] 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:

Last known temperature reading is [ mqttcogs_get topic='mysensors_out/99/2/1/0/0' field='payload']C  
taken at [ mqttcogs_get topic='mysensors_out/99/2/1/0/0' field='datetime' dateformat='Y-m-d H:i:s' local='false']

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!




Publish Data Using An MqttCogs Shortcode

Not only can you visualize data using Mqttcogs but it is also possible to publish data to your Mqtt broker using the [mqttcogs_set] shortcode. The ability to publish data is useful, here are a couple of reasons I wanted to do this.

Number 1: I can publish data directly to my blog without having to use a generic Mqtt client.

Number 2: In the IOT (internet of things) world iot devices can be controlled by publishing appropriate messages. For example, you might be able to control your outside lights by publishing to a topic such as myhouse\lights\outside.

Remember though – you can’t have just ANYONE publishing to your broker!!

Lets start with a basic example

If you want to see the results on the page you need to subscribe to this blog and make sure you are logged in. You need to have a role of ‘subscriber’ to have the ability to publish on this page. If you aren’t logged in, you’ll see the code & graph only.

I decided to open this up. If there is a lot of ‘spam-a-lot’ then I’ll put the restriction back in. I’ve added the strikethrough to the shortcode attributes below so that you can see what I removed.

Here is the code for the graph and underneath the shortcode for publishing to the tests/blog/publishingdata topic. The results are shown underneath.

[ mqttcogs_drawgoogle options="{width:'100%'}" ]
       [ mqttcogs_data topics="tests/blog/publishingdata" ]
[ /mqttcogs_drawgoogle]

[ mqttcogs_set topic='tests/blog/publishingdata'
     minrole='Subscriber' 
     label_text='Enter a new value here:' ] 

I have used the [ mqttcogs_set ] shortcode. You’ll notice that the field is automatically populated with the last value stored in the database. I’ve used the minimum number of attributes in the shortcode that I could get away with.

topic – the fixed topic to send the new messages to
minrole – the minimum wordpress role that is required for the fields to be displayed
label_text – the label shown above the field

….but you’ll notice a problem! There is no field validation. I could enter anything into the field and it will published!!

You’ll also notice that adding a new value doesn’t automatically update the graph. The graph refresh is independent of the ‘add’. There is no link between the add and the visualization. You will need to wait until the next ‘refresh’ time for the graph to update.

Lets add some validation!

Validation is applied in the browser by using HTML5 validation. There are a number of attributes starting ‘input_’. Each is mapped directly to a HTML5 attribute on the input element. You can even change the input type to ‘range’ or ‘number’ but more about this later.

Ok, so we’ll update the attributes in the shortcode to make the field accept numeric integer values only between 0 and 50.

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	minrole='Subscriber' 
	label_text='Enter a new value here:'  
	input_type='number' 
	input_min='0' 
	input_max='50' 
	input_title='Please enter a whole number between 0 and 50' ]

We’ve now restricted the field to accept values between 0 and 50. It’ll also notify the user if the input is invalid. Our numerical entry now looks like this:

Validation to 2 decimal places

I might decide that actually I want to allow decimals, say to 2 decimal places. I could achieve this using the HTML5 step attibute:

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	minrole='Subscriber'
	label_text='Enter a new value here:'
	input_type='number' 
	input_min='0'
	input_max='50'
	input_step='0.01'
	input_title='Please enter a number between 0 and 50 to 2dp maximum' ]

You can even do sliders

You can do this by setting the input_type to ‘range’. What is rendered will depend on your browser. The result isn’t particularly pretty in firefox. There is no feedback showing what the current slider value actually is.

A full list of supported HTML5 shortcode attributes are documented here

Ok, so this isn’t very pretty?

Being pretty has never been my strongpoint. There is also a ‘class’ shortcode attribute. So we can tidy things up by specifying a class to apply

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	text='Add'
	label_text='Enter a new value here:'
	minrole='Subscriber'
	input_type='number'
	input_min='0'
	input_max='50'
	input_title='Please enter a number between 0 and 50' 
	class='mqttcogs_set' ]

My css looks something like this. I added this under the Appearance…Custom CSS option in the wordpress menu.

.mqttcogs_set label {
	display:block;
} 
.mqttcogs_set input {
	display:inline-block;
	margin-right:5px; 
} 

.mqttcogs_set input[type="text"] { 
	margin-bottom: 10px;   width:66%; 
}

….the result now looks like this. A little better!