Table of contents

Tuesday, 21 April 2015

Solar powered wireless weather station - part 2


Over the weekend I have built a prototype of a sensor/transmitter.  The only job it will have to do is:
-  wake up periodically
-  power up the sensors
-  read: temperature (DS18B20), humidity (DHT11), light (LDR), battery voltage
-  send a package using NRF24L01+
-  power off the sensors
-  go back to sleep



Having this setup on a breadboard I have written a very simple program using Arduino (my goal is to write optimised code in C, but at this stage I just wanted to prove the concept).

After compilation, Transmitter.ino takes 14kB (15k with serial output) of available 32kB flash in ATmega328P. One thing I don’t like in my program is that I have hardcoded the sensor ID – it means that if I wanted 10 sensors I would need to flash 10 different programs.

I think I will add 4 or 5-way dip-switch allowing me to choose one of 15 or 31 addresses (the receiver has ID=0 hence only 15/31 are left for the sensors).

I hooked it up to a solar power bank (it has 2600mAh LiPo battery). I have connected the uC directly to the battery (4.1V max. once charged) but I had to add 1N4148 diode before the radio transceiver (it operates at 3.3V). Using a variable PSU I have discovered that everything works fine until 3.1V (minus voltage drop on the diode for the radio), then the DHT11 humidity sensor goes mental (0% humidity) and then at 2.9V the radio stops transmitting (which is good as I’m already getting rubbish readings at this voltage).

The solar bank circuit shuts off the step-up converter if there is nothing plugged in to the 5V USB port (which is good in my case as I’m connecting the uC to the battery directly) but the solar circuit works and charges the battery if enough light is provided.

The funny thing is that it has a built-in LED indicating charging the battery.
In specific conditions (little amount of sunlight) the solar panel was producing enough voltage to trigger the LED on, which was draining the built-in battery...
I don’t have exact figures off the top of my head but it was something like 3mA going from the panel and additional 6mA from the battery (?!?). After cutting off the LED, the current started to flow into the battery J
It wasn’t of course a problem in a direct sunlight but even then, the LED was consuming more energy than my complete circuit will.


The receiver is just another Arduino with NRF24L01+, formatting and forwarding the packet to the serial port. Receiver.ino – 8kB of flash (or 10k with serial output).

Here is an example of what comes out of transmitter:

27: 220C 3323V 40% 299
WRITE OK

27        - sensor’s packet counter
220C      - temperature: 22.0C
3323V     - battery voltage: 3.323V
40%       - humidity (0-99%)
299       - light amount (0-1023)
WRITE OK  - NRF24L01+ acknowledgment


And here is how it looks in a serial monitor on the receiver’s side:

260-27: 1  220C  3323V  40%  299

260    - receiver’s packet counter
27     - received sensor’s packet counter
1      - senor ID (extracted from transmission header)
220C   - received temperature: 22.0C
3323V  - received voltage: 3.323V
40%    - received humidity (0-99%)
299    - received light amount (0-1023)


The next step I’m thinking of is building a second sensor/transmitter and a better, standalone receiver, probably with some LCD displaying the readings.


All comments/support appreciated as usual.


Cheers,
LJ


If you like my project and/or you would like to support it, please use the Donate button ☺ 
Follow me on Twitter, Google+, YouTube, Thingiverse or by email to receive the latest updates.



Thursday, 9 April 2015

Solar powered wireless weather station - part 1


As TheLAMPA project needs to be put on hold – some parts are on the way, I have decided to start a new one.

This time it will be a solar powered wireless weather station. The concept is:
  1. 10-12 transmitters with solar panels + rechargeable batteries. Each transmitter would send: temperature, humidity, light and battery voltage. 
  2. 1 main station that collects and processes all the data. #
  3. add a screen to the main station to present the data + SD card to keep the recordings/draw history plot. 
  4. OR use a cheap tablet just to  present the data (this would save me a lot of time reinventing the wheel as I would have a large screen with proper driver, lots of memory, nice casing, SQLite, etc. right out of the box.  
Thoughts: 
  1. I’m thinking of ATmega328P, sleeping constantly and waking up every 10-20 seconds, powering up all the sensors, reading temperature from DS18B20, humidity from DHT11, light amount (LDR), voltage of the battery, sending a package over NRF24L01+, turning off all the peripherals and going back to sleep. This would be powered from a  solar mobile charger that has built in Li-ion or LiPo battery. 
  2. Main station would never sleep, constantly waiting for incoming packages from sensors. Each sensor would have unique ID so it will be easy to understand where the data is coming from. Additional it would have a pressure sensor (probably BMP180). 
  3. Long and painful process to implement all the libraries for SD card, graphical LCD, etc. Also, smaller (and cheaper) screens will not show all the data (10 sensors sending 4 values = 40 numbers to present). That’s why I think solution 3b is better 
  4. I would need to add Bluetooth support (probably HC-06) to the main station and then pair it with a tablet/phone. Additional piece of work would be to write a mobile app to present the data but in my opinion it is much easier task than doing it on a microcontroller. Also, the crappiest tablets have at least 256MB of ram, 4-8GB of storage with a screen of at least 1024x600 (most of the time it is 1280x800), clock, nice cover, charging circuit, possibility to install additional apps/libraries when required, SQLite to keep all the historical data. Let’s say that each sensor sends:
    • ID (1-15) – 1 byte (unsigned byte) 
    • Temp -30.0C...+50.0C without decimal point (-300...+500) – 2 bytes (signed char) 
    • Humidity (00-99%) – 1 byte (unsigned byte) 
    • Light (v1) (0-1023) – 2 bytes (unsigned char) 
    • Light (v2) (00-99%) – 1 byte (unsigned byte) 
    • Voltage without decimal point (500 for 5.00V) – 2 bytes (unsigned char) 
    It means I would need 8 bytes of storage per record. 10 sensors = 80 bytes. Even with sending the readings every 10 seconds, I would need to store 80b x 6 times a minute = 0.5kb per minute, which gives 720kb per day. So it is 250MB per year. With 4GB of available memory I could store up to 16 years of historical data. 16GB SD card would provide a lifetime storage.


If you like my project and/or you would like to support it, please use the Donate button ☺ 

Follow me on Twitter, Google+, Thingiverse, YouTube or by email to receive the latest updates.



Thursday, 21 August 2014

TheLAMPA – remote controlled, adjustable workbench lamp – part 1


The following post is the first part of a series about my most recent project I’m working on, TheLAMPA. I hope you will like it.

As this is a live project I will be writing new posts along with the progress I make.

I will share my considerations, failures, difficulties, etc. If you have any suggestions, advices (good or bad ) or simply want to help - please leave a comment.  Thank you!

Ok, here we go ☺ 

I have bought a lamp in IKEA recently:  


The lamp is sort of a billiard-lamp shape type. The central part (aluminium H-shaped profile, 80x6x2cm) holds a fluorescent bulb. Then, it has 10cm wide aluminium ‘strap’ running around as a shade.

Ok, it may be quicker to draw it in a MS Paint ☺

This is a top view (the fluorescent tube sits in the middle rectangular part):
 

This is what I would like to do:
  • leave the H-shaped profile untouched and hide there all the electronics, drivers, motors, pulleys, etc.
  • put 16 LED MR16 “bulbs” between the H profile and the shade
  • print mounting brackets for the MR16 sockets and bolt them to the H profile 
  • use only 1 switching-mode power supply, 230V to 12V for the LEDs. For the electronics a simple 5V stabiliser may be enough 
  • use ATmega328P microcontroller to drive the whole thing. The code will be written probably in Arduino IDE as there are plenty of libraries supporting all the hardware I may need for this project.

The program however, will be responsible for:
  • Controlling each LED independently.
    I plan to use PWM (Pulse Width Modulation) – this will allow me to change the brightness of each LED (and of course turn it on and off).
    PWM works in a way that a high frequency square waveform is used (usually between 10kHz and 100kHz) so the eye will not see the flicker. The only variable is the pulse width/duration (how long in a single period the logical ‘1’ is on). If a factor is 50% it means, the HIGH state is for 50% of the time, same as the LOW state (all this happens thousands times a second). If the factor is 100% - it means the LED will be powered constantly. Same with factors like: 10%, 17%, 80%, etc... the LED will be in the ON state just for a proportional time, and then off for the rest. It will be blinking but the eye will not see it - it will be just an average light which will appear dim.
    Seems that TLC5940 is a perfect fit for this purpose. Also, by using different LED types I will get different colour temperatures which could be used for different purposes.
  • Receiving commands from a TV remote controller.
    A popular IR sensor TSOP31238 and a piece of code to understand what the remote controller is saying. Then just implementing actions based on commands received. Instead of using bunch of inputs in the microcontroller for a keyboard I will use only one – to read the data from the IR sensor. I will need to read all the codes first to know which code is assigned to which button. And then I can use the codes in a program. I’m thinking of using Volume Up/Down buttons to change the brightness and the Channel Up/Down buttons to change the height. Also, I’m thinking about making it more advanced, for example pressing a TXT button followed by “90” will make the light 90% or another button followed by “30” will lift the lamp by 30cm. POWER could turn the lamp off and pull it to the highest, park position. And so on, and so on
  • Controlling 2 motors to lift/lower the lamp.
    This will be a bit challenging as I would need to rethink few cases. At the minute I’m thinking about using 2 servos – these are incredibly strong (they have built-in gears already) and very small. The issue is that they only have 270 degrees freedom. I need to take the servo apart and remove the lock. Then it will rotate freely 360 degrees. But... the other issue is that it will not hold the position. A small servo can be turned by hand so the gravity may/will pull the lamp down once the power is disconnected :/  The solution may be to use a worm gear. The construction allows only one direction of driving it – the small, “threaded” gear turns the large one but not the other way around – this is exactly what I need. I’m going to print a cylinder with grooves to allow the lifting string to wind nicely (and not on top of each other, tangling) but this introduces another issue I need to solve: let’s say I want to have a working distance of 1m and the cylinder has 1cm in diameter (remember, we are working in a tight space within the lamp). It means that circumference will be just over 3cm (2*PI*r) so I would need 32 turns to get it done. If I’m going to lie the string every 1mm it will give me a barrel of 35mm in length... not good...
    OR... I could print a big, narrow gear with a string-thick groove in the middle – then the string will be rolled on top of the previous layer. This will eliminate the previous issue but will cause inconsistent lifting speed (as the diameter will change with every layer) and it will be a bit harder for the motor as well (higher = more string = greater diameter = more string to be pulled during one revolution). But if the worm gear will be used – this should not be a problem at all. In this case I may need a faster motor than a servo as one rotation of the worm gear will rotate the big one just by 1 tooth. I will need to test if first as it may be just right ☺  Also, I don’t want to wait 10 minutes for the lamp to arrive where I need it.
  • Reading data from acceleration sensor to make sure the lamp is level (it will be impossible to make identical movement with 2 separate motors). I would like to read the slope degree during lifting/lowering and if the lamp is off more than... 5 degrees? then I will stop/slow down one of the motors and speed up the other one to make the lamp level again. I have two candidates of accelerometers. Basically the same price but one is digital, the other on is analogue. In this project I don’t need super high precision or fast data rate.
    In digital accelerometer I would need to write a protocol to communicate with it, play with configuration registers, read a full set of data, understand it, and then extract only the part I need…
    The analogue one is much easier to implement as it returns a voltage depending on a position of the accelerometer. It returns 3 separate voltages (for X-Y-Z axis) but I’m interested only in one axis so I can use just one pin of the microcontroller to feed it to the built in Analogue-Digital Converter. The choice is: the analogue one, MMA7361.
    The datasheet says 1.65V is zero-g for an axis, so it is „level”. The program needs to consider if the voltage is lower, it need to lift one end, if higher – the other one, until the voltage gets back to 1.65V (with some hysteresis of course).
  • Showing current status on a display.
    A 7 segment, 4 digit display should be enough for the use. By pressing a button it may show the status, height, brightness, selected LED, etc. For example, pressing a MUTE button may show „LED” string, then pressing 5, may show „LED5” - changing settings for 5th LED. Changing height will show the distance, etc.
    I’m also thinking about using a standard, 2x16 LCD screen but from a distance of 1-2m (when the lamp is under a ceiling) it may be hard to read. I could use a library with custom characters, to write big characters using both lines of the LCD but then, I would get the same 3-4 characters display with much worse clarity and viewing angles than the bright and sharp LED display.
  • Recognising lamp’s position/height - another „problematic” point.
    • To measure the position of the lamp I could use ultrasonic distance sensor or an infrared one. If I mounted it on the lamp, pointed upwards I would know how far the ceiling is. But the problem is... dust. After a period of time I will be getting wrong measurements. I could mount it under the ceiling but this will introduce another set of visible wires going to the main board inside the lamp
    • The other option is to use a set of infrared emitter-receiver line and mount it somewhere beside the cylinder with the wire reel. The beam should be broken only when the reel is full/empty (meaning 2 sets of transmitters per motor). The downside of the solution is that this will be very hard to calibrate, align, get repetitive results.
    • 3rd option – multiturn potentiometer. I would need to pick the correct one – depends how many turns the motor/barrel will do for the full range of movement. Let’s say it is 80 revolutions – I could use 100-turn potentiometer. This will give me a safe margin for use the pot without breaking it, giving 80% of its range. Good enough for this project. ATmega328P microcontroller has a 10 bit ADC, it can recognise 1024 levels. In this case it will be „only” 800 positions (if I use a full range of the potentiometer) which gives me resolution of 1.25mm (for the distance of 1m). This is just to know the position of the lamp. The accelerometer will be used to make the lamp level. Also, it will be possible to know where the lamp is after booting up by simply reading the value of the potentiometer.
  • Saving/recalling ‘favourite’ height/brightness.
    The microcontroller has 1kB of EEPROM, so it can store 1024 8-bit values. It will not be erased when the power is off. To store 1 favourite height position and brightness I will need: 1 memory cell to store the height (0-100% or 0-100cm, both figures fit in 8-bit datatype), and then brightness: the PWM can be driven using 8-bit variable, it has 256 levels – same story, just 1 byte per value. Even having 16 LEDs + height position I will need only 17 cells of memory per one favourite setting - it means I could store 1024/17 = 60 settings. I will probably stick to 10 only (easily accessible using buttons 0-9 on a remote controller + a dedicated button to store or recall the settings). 


I have decided to go with LEDs as they use much less power and are more efficient comparing to halogen bulbs – I don’t want to have a 300W heater just beside my head. Also, they are not getting that hot so the printed plastic holders will not melt and also, I will not get my forehead skin peeled off when I touch the bulb accidentally ☺ (for high density boards I may need a lot of light so the lamp will be hanging very low).

I’m hoping to write the next part soon, once I get my head around the above and prepare some materials.


If you like my project and/or you would like to support it, please use the Donate button ☺ 


Follow me on Twitter, Google+, Thingiverse, YouTube or by email to receive the latest updates.