For our latest Build Night we received a few Solar Panels from Brown Dog Gadgets. Myself enjoying lots of quality time with lightweight SDR radios decided to prototype a small outdoor digital radio transmitter. At a previous Build Nights we received some fine Spark Core boards. Combining this with an RFM12B radio transmitter occurred to me to be low-power enough to be driven by the solar panel.
Step 1: Setting Up the Spark Core With the Solar Panel
Being located in the inner city in a basement does not bode well for those who want to experiment with solar power. Preparations for expeditions to the surface take a lot of effort, luckily one can do brief measurements while the evil day-star is still strong and work in safety for most of the time.
Our "sophisticated" measurement device helped me to test the electrical output of the solar panel. By measuring the output voltages on the red and the black wire I compared the results against the same solar panel being "driven" by two desk lamps. Both samples (outdoor and desk lamps) varied around 4.5V. That seems enough to drive the Spark Core and the radio.
Step 2: Hooking Up the RFM12b to the Sparkcore and the Solar Panel
Hooking up all the devices is pretty easy, the solar panel is simply connected to the USB port of the Spark Core, and we replace the sun with two desk lamps. The RFM12b and the Spark Core communicate over traditional SPI, so we need to connect 6 wires:
Spark Core pin - RFM pin ======================== A2 - SS A3 - SCK A4 - MISO A5 - MOSI GND - GND 3.3V - 3.3V
To reduce noise from the active electronic components I placed the radio farther away using a HDD ribbon cable, you could just as well use the breadboard with appropriate wires.
Step 3: Running Code on the Spark Core
To compile the code I wrote we need a cross-compile toolchain for the ARM Cortex M3 platform. I used gcc-linux-arm-gnueabi.
Being somewhat conservative I decided to go with JTAG/DFU for getting my code onto the sparkcore. By default the JTAG/DFU mode on the Cpark Core is not enabled, so after powering it up you have to press the reset button briefly while pressing mode button for at least 3 more seconds, when successful the main LED should flash with yellowish color - the Spark Core firmware GitHub page does a good job of explaining this and to flash your firmware, of course you can also use the cloud-based approach to uploading.
Or use DFU like me, Using the command:
dfu-util -d 1d50:607f -a 0 -s 0x08005000:leave -D tx.bin
I flashed a simple program that sends out the string "Hello World" and a bunch of other binary data every second. See the GitHub page for the code. Anyway, you should make sure that while flashing you have a reliable power-source, you'd probably want to avoid flashing the Spark Core using the cloud while powered by the solar panel.
Step 4: Indoor Testing
After flashing the code to the Spark Core, all there is to make sure the RFM12b and the solar panel is connected and the solar panel gets enough light. For testing the setup indoors two desk lamps were used.
The next day at around ten o'clock I put the Spark Core and the RFM12b in a cardboard box and connected the solar panel to run tests on the transmitter.
After making sure there is a transmission, I set up a signal power sensor on the RTL-SDR, using the command
while true; do rtl_power -f 433.8M:434.2M:8k -c 25% -i 15 -e 10m >>solar.csv; done
This ensured that I know exactly when the radio stops transmitting, and can generate a nice graph out of it using gnuplot. You can enjoy the results of this a few pictures later.
Later during the day I checked again using linrad, and we can see, the afternoon sun providing us with a somewhat weaker but still clear signal.
And then later right after the sun disappeared behind some buildings in the evening, the signal is barely visible.
Finally it faded about 10 minutes later completely and the Spark Core stopped running.
The signal was there all day (see white image; only my radio was tuned elsewhere around 16:00)
Step 5: Decoding the Data
The message the transmitter was sending was "Hello World" followed by 106 bytes counting from 0 upwards, followed by 32 binary zeros, followed by 32 binary ones, tailed by 64 bytes containing the number 85. To receive this message, I connected my RTL-SDR, set up a gnuradio application (see image).
After some tuning on the knobs/sliders I started to see bit-patterns emerging. This demodulated bit-stream is dumped in a file for later processing. The captured bit-stream can be piped through a simple decoder that I wrote. After consulting the Spark Core datasheet and getting the timing right with the Spark Core, the following message was captured and decoded:
'Hello World\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghij\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd5UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU\n'
Calculating the correct timing involves dividing the clock rate of the Spark Core with the bit-rate of the radio transmission.
Step 6: Resources
All the code that was used on the Spark Core and the demodulator and decoder is available on GitHub.