Sunday, January 26, 2014

434Mhz RF Transmitter/Receiver with the Arduino Micro

I wanted to experiment with the RF Link transmitter/receiver for my wireless projects. With the temperature around here going from below 0 to 60 degrees, a wireless temperature sensor would be nice! The project is to get data from an analog temperature sensor and use an RF link to transmit the data to a receiving device.

The Parts List:

Temperature Sensor and RF Transmitter:
Arduino Micro Board  ($22.95) 

RF Receiver side data collection and processing:
RF Link Receiver - 4800bps (434MHz) ($4.95)
 Arduino Mega 2560 I had this on hand, however a Micro, Uno or other Arduino board can be used instead as long as it has a UART + USB Serial (if you want to use it).


Total Estimated Cost ~  ($29 for Transmitter  +$28 for Receiver)

Click here to get the code for this project



Circuit Setup

The RF Link receiver and transmitter pair are the interesting part of this project. With these two guys, you can add one way communications with only a UART on each side.  I choose to use the Arduino board serial since I happened to have a couple of boards on hand and using the serial interface from these boards is very easy compared to the other ways of getting the serial data these components (i.e. software serial or virtual wire). This RF Link pair gets A LOT of noise, and that noise comes in as garbage data that has to be filtered out using a protocol that is robust enough to recognize the data you want to send and receive. The protocol and filtering is the key to getting reliable data from these guys!


Hooking up the RF Link Receiver


Here is the pin out for the RF Link receiver from the datasheet. Even though it has 8 pins, It's really four connections, Ground, 5V power, Digital Out to the RX of the serial port and the antenna on Pin 8.



Connections:
Pins 1, 6, 8    -> Ground  from Arduino Mega
Pin 8              -> 13 cm wire to act as an antenna
Pins 4, 5         -> 5V from Arduino Mega
Pin 2              -> Connected to RX3 (pin 15 on the Arduino Mega)



Hooking up the RF Link Transmitter to the Arduino Micro


Here is the datasheet for the RF Transmitter module. This module only has 4 pins so it's pretty easy to hookup. I used 5V to power it from the Micro but it can actually take up to 12V if you want better range!

Connections:
GND  -> Ground on Arduino Micro
DataIn -> TX pin on Arduino Micro
Vcc     -> 5V from Arduino Micro
ANT   -> 13 cm wire used as an antenna


Hooking up the TMP36 Temperature Sensor

Adafruit has an excellent tutorial to explain how to hook up the temperature sensor and much more Adafruit TMP36 sensor tutorial.



Connections:
Vcc   -> 3.3V on Arduino Micro                 (TMP36 Pin 1 on left when looking at flat side of sensor)
Vout  -> A0 analog input on Arduino Micro (TMP36 Center Pin)
Gnd   -> Ground on Arduino Micro             (TMP36 Pin 3 on right when looking at flat side of sensor)

The datasheet also shows a 0.1uF power supply coupling capacitor from the supply voltage pin to ground. I added this directly accross the leads on the TMP36 to help regulate any input voltage fluctuation. (not shown in picture below).
I also used the Analog Reference voltage at 3.3V instead of the 5V default by connecting the 3.3V pin on the Micro to the AREF pin (just to the right of the 3.3V pin).

CAUTION: If you connect the GND pins and Vcc pins backwards, your TMP36 will get very very hot and eventually this will burn out your sensor!


RF Transmitter and Temperature Sensor Circuit

The Code

The challenge in creating an RF link with these components is filtering out the bad data so that you can more reliably get the data you want!  These guys make a pretty noisy RF link so you can expect to get lots of garbage data (at least when using 5V to power the transmitter). The way to filter out the garbage data is to establishing a protocol for sending and receiving data.

Basically, a protocol is an agreed upon data format that is unlikely to occur in random data. Having a protocol allows the receiving code to know what to expect. There are a lot of ways to do this. You might send begin and end markers around the data and check to make sure you got both on the receiving side. A protocol may also send and check the size of the data packet along with the data to help the receiving side verify that the amount of data received is correct. The transmission could include the CRC of the data packet and the receiver could check it on the other end to verify that the data received is what was expected.
You can't prevent the receiver from getting bad data, but you can decide what the receiver will do with it.

I choose to establish a very simple protocol for my project using the word "Temp" as a sequence of characters that will proceed each temperature reading sent by the Transmitter. The temperature reading is a decimal and can be either a positive or negative number. So the only valid data the receiver should ever expect to get would look something like:
Temp70.58

The receiving code will exclude all data that doesn't match the expected data format established above. Ascii character codes are used for filter data. If the word Temp is not received or if bad data that doesn't meet the criteria for expected data, the data should be ignored. The received data is not always perfect so validation still needs to be added to ensure that only good data is used. Also, the transmitter is set to send a new value every 5 seconds, this is probably more often then I would like but it is good for testing!



Thursday, January 23, 2014

Fast Fourier Transform FFT in C++

Hi Everyone,

So not too long ago I was playing around with doing some FFT's from mic data I collected. I found a rather simple C algorithm and made made a C++ class out of it. Also I added the ability to load the data from a file so it would be simple to get results for given data set. Of course I'm sure there are tons of FFT classes out there but this pretty much sticks to the basics so you build what you want on top. I also just got a git hub account and so this is also my first git hub post. Cheers!

Tuesday, January 14, 2014

Electric Imp Battery Power

I really wanted my motion sensor to be battery operated. The Imp takes ALOT of power. 90mA for the WiFi alone! Which does not yet have a low power mode option.  So how long can it go on a Battery anyway? I add a Lithium Ion Polymer Battery - 3.7v 2500mAh ($14.95) to my motion sensor project to test this out. I connected a fully charged rechargable LiPo battery to the P+ and P- terminals on the April board to run the motion sensor imp project I had.

Here's how you connect the battery:
  1. Remove the Imp from the April board  and unplug it from the USB before connecting external power. 
  2. Make sure you move the Jumper to the Battery position. 
  3. Connect the battery + to the P+ solder point and the battery - to the P- solder point on the April board. Don't use Vin and Ground to connect the battery power, they are not safe!


That's really all there is to it! If you are sure you did the above things correctly, put the Imp back in the April board and it should have power and connect to the WiFi as usual.

Keep in mind though, this solution will only provide power for a few days at a time! In my first test with the battery connected, the battery lasted for a little over 2 days.




Electric Imp - Hello World Motion Sensor to Email

I recently decided to re-do a motion sensor project I had previously with an Arduino Board, but this time using the Electric Imp.  The Electric Imp looks just like an SD card, but don't be fooled - it won't work in an actual SD card slot. You need an April board or similar breakout for this little devil.

You might feel a bit nutty if you use one! That's because the Electric Imp - IDE  is through the Electric Imp cloud site with all of the code written in Squirrel. This is great for projects that you want to be Internet accessible.

This Electric Imp IDE makes this project easy!  The IDE runs entirely from their website and which also provides server side processing capability for your Imp projects. First you have to register the Electric Imp and set the network credentials using the blink up procedures found in the Getting Started Guide and Documents.

The Electric Imp Motion Sensor

I wanted to hook up my motion sensor to my Electric Imp an have it Email me when motion was detected.
I also wanted to hook up battery power so it would be wireless.

Here is the full parts list:

  1. Electric Imp ($29.95)
  2. Electric Imp April Board basic breakout (12.95)
  3. PIR Motion Sensor ( $10.99)
  4. Small Perma-Proto board I had on hand ($2.95)
  5. Some wire that I had on hand to make the connections (~$3.00) 
  6. (optional) Small Breadboard for prototyping I had on hand ($5.00)
  7. (optional) Lithium Ion Polymer Battery - 3.7v 2500mAh  ($14.95)
The total cost to make the project (not including the battery) is about $60 + taxes and shipping.


The PIR Motion sensor pin is connected to pin 1 of the Imp, configured for input. The other two pins on the motion sensor just provide power (connected to Vcc and ground). And that's really the whole circuit for the motion sensor.  It's important to use pin 1 for it's wake up feature. This let's the Imp sleep until pin 1 changes, so no looping! The Imp also has built in light detector capability and it can tell you it's voltage supply too. So I decided to have it email me all three when the motion detector is triggered. 

Here is the device code:
motion <- hardware.pin1;
function readPin(){  if(motion.read() == 1)  {     local current_light = hardware.lightlevel();     local voltage = hardware.voltage();          server.log("Motion Detected - Light Level:" + current_light + " - Voltage:" + voltage);     agent.send("motionDetected", "Motion Detected - Light Level:" + current_light + " - Voltage:" + voltage);  } }
motion.configure(DIGITAL_IN_WAKEUP, readPin); 

The line in the device code of the form:
      agent.send(agentMethodToCall, objectToPassToAgentMethod); 
tells the agent code on the server to call the specified method (in this case the motionDetected method).

I wanted my motion sensor to send an email message when motion is detected. On the Arduino I used the serial port to talk to a c# application on my computer that used SMP to send an email. However, I want to take advantage of the server side processing on the Imp for this feature.  This turned out to be very simply if you use a free emailing service such as MailGun. A very complete guide for writing the agent code to send mail using MailGun can be found Using MailGun with Electric Imp.




Saturday, January 11, 2014

Trinket - Color by Sound RGB NeoPixels

I wanted to experiment with the NeoPixels and the Trinket so I decided to make sound reactive lights. The Adafruit NeoPixels are nice. They can be chained together and require only one IO pin to stream data to a chained strand. I chained 4 of them together for this project I also used an microphone breakout available from Adafruit.

Here is the full parts list:

  1.  Adafruit Trinket 3V Logic   ( $7.95)
  2. Max 4466 Mic Amp  ($6.95)
  3. Some wire that I had on hand to make the connections (~$3.00) 
  4. (optional) Small Breadboard for prototyping I had on hand  ($5.00)
  5. (optional) An Arduino Micro Board I used for collecting data and prototyping ($22.95) 

The total cost to make the project is about $20 + taxes and shipping.


 Get the Trinket code for this project here..

The Project

 I wanted to set the color of the lights based on the frequency of the sound detected, or something close to that using the Trinket. To do real frequency detection I was thinking I'd need to do FFT  (Fast Fourier Transform) processing in real time. This seemed like it might be too much calculation for the little trinket so I decided to do something a little less intensive,  I took a look at the Mic data to see what might be possible. I used the Arduino Micro to do data collection from the Mic because it has something the Trinket doesn't have, USB Serial communications.

Data Collection

First, I collected Mic sample data using the Arduino Micro's USB Serial to see what the data looked like. I wrote some code  in the setup method to output data collections of 2048 samples of the Mic data collected directly from analog input on pin 8 of the Micro. I collected data for three situations: quiet ambient noise, Heavy Metal music playing, and some rather average music playing. The sample data is shown below.
Quiet Noise (2046 Samples)
Heavy Metal (2048 Samples)
Average Music (2048 Samples)
The data showed that the baseline Mic noise level was always about the same, roughly just above 500. Of course, there was a lot of variation in the heavy metal data and a less variation in the average music data with the quiet ambient data being pretty predictable. The samples were polled every 5 ms.

A look at the Slope

The following graph shows the slope calculation from the data collected for average music shown above.

Average Music Slope (2048 Samples)

The nice thing about the slope over the raw data is that it is centered around 0. So no offset level prediction is needed. However, if I change the color of the lights too often, the lights may not update quickly enough nor will my eyes be able to perceive the intended color.

To ensure the lights will be OFF when there is no interesting sound, I exclude slope changes below 100 to make sure it would be above the value typically seen by quiet noise.  To keep the lights from changing color too much or too often, I choose to fade the LEDs in and out.


The Period Dependency

The final variable in this project is the Period between the slope level detection. The get a loose frequency dependency, I track the period of time between slope calculations that exceed 100. Each time the Period changes, the Period is mapped to the colors on the color wheel (0-255) with some scaling to make things more interesting.

Of course, this is not an exact frequency mapping to the sound  but it does provides interesting color variation that depends on the sound playing. 

Tuesday, January 7, 2014

Trinket Pin Mapping for AnalogRead and AnalogWrite

The simple answer to using AnalogRead and AnalogWrite on the Trinket, the pins numbers are not the same as the labeled digital pin numbers. Also not all of the pins that can be used for AnalogRead, can be used for AnalogWrite.  The pins are labeled for digital Read and Write. Here is the mapping:

Digital Pin 0 -> analogWrite(0)
Digital Pin 1 -> analogWrite(1)
Digital Pin 2 -> analogRead(1)
Digital Pin 3 -> analogRead(3)
Digital Pin 4 -> analogRead(2)

More information on the pins and can be found here:
http://learn.adafruit.com/introducing-trinket/pinouts




Sunday, January 5, 2014

Programming the Trinket with the Arduino IDE in Windows

I am using the Windows Arduino IDE to program the Trinket. This has been trying at times so I thought I'd share my experiences here. You can find a lot of information on solving problems on the Adafruit website, but I find it takes a while to get to what your looking for. Hopefully this will save some headaches for others who might also like to use the Trinket.

  To get started, make sure you've done these things:


  1. Updated the ATTiny85 section of your avrdude.conf file.
  2. For windows, make sure to install the USBtiny drivers 
  3. Under Tools->Board Menu select the Adafruit Trinket 8MHz
  4. Under Tools->Programmer select USBtinyISP

  Note: The Trinket doesn't have a USB Serial interface so you won't see a COM port for it.

 To upload to the Trinket, these instructions are handy: 

  1) Under Tools->Board Menu Adafruit Trinket 8MHz is selected.
  2) Under Tools->Programmer USBtinyISP is selected.

  The next steps are timing critical:
  3) Press Ctrl+Shift+U to Upload code using the programmer. (The sketch will start compiling)
  4) Press the button (don't hold it down!) on the Trinket toward the end of the sketch compiling, you want          the red LED to be blinking when the code is trying to upload.
  5) The red LED on the Trinket should pulse. This means it is ready to receive the sketch.
  6) WATCH the RED LED!!  If your sketch is uploaded, it should turn solid briefly before going off.
       If the red LED turns solid, it is likely that your sketch uploaded even if you get an error.

 Problems I had and things I did to fix them: 

 Problem:  
      The red LED does not flash when I press the reset button and I always get the error message below when trying to upload.
      avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)
   Try: 
      -  Unplug the Trinket and plug it back in.
       -  If using a USB port on your computer, try using an old USB 2.0 HUB if you have one. This has been much more reliable for me. An error is usually reported but the sketch still uploads and runs.
 Problem
      When trying to upload, the red LED was flashing but it did not turn solid, my code did not upload and I got an error:
      avrdude: Error: Could not find USBtiny device (0x1781/0xc9f)
  Try:
     -  You probably missed the time window for the upload. Try again, and wait longer before pressing the button the Trinket. (This happens A LOT!)

  Problem:
       When trying to upload, the red LED was flashing but I got an error:
        avrdude: error: usbtiny_receive: usb_control_msg: sending control message failed, win error: A device attached to the system is not functioning. (expected 4, got -5)
  Try:
     - Did the red LED turn solid? If so, your sketch is likely to have uploaded anyway.
     - If not, make sure your avrdude.conf is updated.

  Problem:
       When trying to upload, the red LED was flashing but it did not turn solid, my code did not upload and I got an error:
       error at ...  avrdude.conf:1524 unrecognized character: "i"
  Try:
     - Comment out line 1524 in the avrdude.conf file which reads in my file:
             is_at90s1200     = yes;
 ( you can comment out the line by putting a # sign in front of it. )

   More avrdude problem solving for the Trinket ( or Gemma) ...

Saturday, January 4, 2014

Experimenting with the Adafruit Trinket ATTINY85

I've been doing some projects with this board testing it out. For under $8 the Trinket offers 8MHz (overclocking to 16 MHz is software possible on the 5V version). It has 8K of  memory which is enough to do a lot of smaller projects. With it's 5 multi-purpose digital pins it's very versatile and an easy choice for inexpensive projects. The best resource for getting started with the board is of course on the Adafruit site: http://learn.adafruit.com/introducing-trinket/introduction.

However,  I would not recommend this board as the first board to try for someone new to micro controllers. The programming process a bit tricky compared to other boards like the Arduino Mega, Uno, and Micro for example. Also, the board does not have Serial USB capability like other boards have so it's very difficult to debug on this board. For anything that is more complex, I have found myself prototyping with the Arduino Micro and then porting it to the Trinket.