Monday, February 16, 2015

Raspberry pi, standalone arduino, 433Mhz wireless communication and 20 voltage sensors



For one of my projects I want to use an arduino to measure voltage for from 20 sensors.

To do that I saw many shield that allow to multiplex voltage source connected to a few arduino. ADCs ... But It's for fun, so I decide to build my onwn including standalone AT328 (see this Arduino link).

Requirements

To begin this is my requirements list :
  • max 20 sensors inputs. Max voltage Vref /AA. 
  • work on battery so as low consumption as I could
  • wireless communication (as cheap as I could)
  • one raspberry pi as server (receive/ persist datas comming from my 328)
I view this project as many phase :
  • proof of concept/validation (is all is working, communication, sensors and so on)
  • optimization / validation (reduce consumption, resolve dysfunction)
  • optimization / validation 
  • end of projet  : build circuit board, solder, put in box , validation

Proof of concept

At this point I have to :
  • choose components
  • prototype this card
  • and when all will work I will thinl about circuit board.

Component list

  • atmel 328  with bootloader (It more expensive as ATmel without bootloader, but one thing at a time)
  • 16 Mhz quartz
  • few resistor and capacitor
  • L7805CV regulator. (I will try LM317 latter)
  • emitter / receiver 433MHz (Warning you should verify if the 433 Mhz use is allowed in your country...)
  • 2 x CD4051 8 channels multiplexer (for test it's enough)
  • raspberry pi (I have a B model with wifi)
  • battery connector

For prototyping 

  • breadboard (I have 2 : 840 points)
  • 1 usb / rs232 converter (to upload sketch in arduino)
  • I have one arduino (will allow me to make comparison)

Schematics

TODO/Work in progress

let's start building

first build an arduino like (see "Building an Arduino on a Breadboard"), at this point I could not test anything except Vcc.
 
Then add an USB to Serial arduino module to be able to push sketch in arduino.


To connect this module  you have to connect
  • +Vcc, 
  • Gnd, 
  • Tx (to atmel328 Rx)
  • Rx (to atmel328 Tx)
  • Reset (to atmel 328 pin 1 reset using a 100nF capacitor)

Note :  At the begining I do not connect the ext reset of my usb to serial card and I had and error during sketch uploading.




At this point I could test my arduino and usb connection.

I use the blink example and connect a LED to pin arduino pin 13. Then push this sketch to my arduino bread board. And... all is ok.

Now it's time to add wireless comunication. I choose a 433Mhz emitter end receiver (very cheap)



In my plan, in want an arduino send periodically information to my raspberry pi. In my mind, at the end I'd like to build a "server ask --> client response" and see if it decrease consumption.

So I had now to connect an emmiter to arduino and the receiver to my raspberry pi, and see if all work toghether.

First I'll start with receiver on raspberry pi.

As I found a lot of informations about internet I saw there difference between RPI revision and GPIO.

What is my RPI model ?

So first I have to identify which RPI model I have.

So I connect the RPI through SSH using moba xterm. And in a terminal I use the command line :

cat /proc/cpuinfo


at the and of the command output you should see something like "Revision : Number"

Go through http://www.magdiblog.fr/divers/connaitre-le-modele-exacte-dun-pi/
and look at your model.

mine is : 000e Model B Revision 2.0 512MB, (Sony)

Ok , let's connect RPI and arduino

see http://www.homautomation.org/2013/09/21/433mhtz-rf-communication-between-arduino-and-raspberry-pi/

Mainly :

Receiver on RPI
  • connect pin GPIO 21 (wiring pi 2; chip 13) on receiver data out
  • GND to GND
  • and 5v to vcc
On arduino side, almost same
  • connect pin 10-PWM (physical 16) on emitter data in
  • GND to GND
  • and 5v to vcc
Connect 20 cm antenna on each device.


Software

For software on both I use RCswith (VirtualWire does not work for me...) see (https://code.google.com/p/rc-switch/)

For RPI I use RFSniffer
on the arduino side the sketch is as in http://www.homautomation.org/2013/09/21/433mhtz-rf-communication-between-arduino-and-raspberry-pi/


And all is working...
Ok now,
  •  due to the nature itself of this protocol, message are received many times... Anyway, just modify the RFSniffer.cpp (as follow) relying on this source (see last program : http://faitmain.org/volume-1/dispositifs.html
  • I want to send more than activity form my arduino... I want to send many data, in fact one for each sensor connected... To do this I have to find or write some kind of protocol wich is allowing to :
    • to identify my arduino card (with an adress)
    • to identify on sensor (relying on multiplexer adress ??? 3 or 6 bit  ie 8 or 16 sensor)
    • to add for each sensor my digital measured value.
|Arduino adress | Sensor adress | value |

 first, what is the max size of a "data packet" ? To determine this I firstly search but could not find. So I use rule of thumb : send bit since reaching the limit... I found that I could send 31 bits (31 + 1 bit for sync I think)

  mySwitch.send(2147483647, 31);

so  I choose
  • 14 bit for base address (0 to 16383) identifier
  • 5 bit for sensor identifier (32 sensors max for each arduino)
  • 12 bit data (0 to 4095)
12 bits for data is enough and pheraps too bignow, because the ADC in atmega 328 is 10 bit. But if I decide to add a more precise ADC in the future those 2 extra bit would be welcome.

At this time on receiver side I could have :



while sending on arduino side :

  mySwitch.send("1111111111000000000000000000100"); // base adress 16368 and sensor value 0
          // and value 4
  mySwitch.send("1111111110010000000000000001000"); // base adress 16356 sensor module 0
          // and value 8

How to send data ?

Before adding multiplexer, I have decide how to send Sensor datas.
What i already know :
  • ADC conversion take 13ADC clock cycles
  • ADC clock is Atmel frequency (16MHz in my case)/ 128 (prescale set toobtain between 50kHz and 200Khz ADC clock for 10bit resolution) , that gives 125KHz. 
  • So the conversion time is 13 cycles / 125KHz = 0.104 * 10^-3 that gives 104 uS

As I could read the ADC frequency could be increase up to 1Mhz without much degradation by changing the prescale.

In my case 1 sensor value send  each minute is more than enough. it means

1 multiplexer adressing + 1 conversion time + 1 send (multiple send beacause of 433 Mhz protocole)
so it means

AAA us +  104 us + BBB us .....

I am missing data, let grasp them.

Multiplexing time

I could try to measure it when  i will have it...

Sending time duration

To have an idea I does :

void loop() {
 unsigned int i;
  for(i=0;i<10;i++) {
   start_times[i] = micros();
   mySwitch.send("1111111111111100000000000000111");
   delay(1000);
   stop_times[i] = micros();

  }
  Serial.println("\n\n--- Results ---");

  for(i=0;i<10;i++) {
   Serial.print(" elapse = ");
   Serial.print(stop_times[i] - start_times[i]);
   Serial.print(" us\n");
  }

That is giving me ~500ms for BBB.

Connecting multiplexer (CD 4051) and Mock sensor

Firstly, I don't want to already use sensor, so I will fake it :
  • Mock sensor : potentiometer gnd, +5V , middle pin to in multiplexer
Then I had a look at http://playground.arduino.cc/learning/4051 about CD4051 and it's enough to wire this CI to my breadboard arduino:
 connect multiplexer pin z (4051) to pin A0
connect the voltage sensor to pin Y0 (4051). As I fake only one entry I connect the  Y1-Y7 to gnd.

And after adding some lines to my sketch I obtain on my Raspberry  :
  Know I have my arduino sending  :
  • an adress (in the future based on DIP switch)
  • a sensor id
  • the sensor value.


What if wifi card is cheaper...

A the very beginning I'd like to use Wifi shield to does exchange with my RPI, but the cost was unaffordable.
Recently I found  an ESP8266 device from 5$ to 8$ ... So I decide to test it. I'm waiting for delivery. After a few test I will probably change the 433Mhz emitter. This evolution will allow to exchange more data in a request-response way with no receiver to install.


I finally received my ESP8266... But I was a little bit optimistic and I missed a couple of important things :
  • ESP8266 run  at 3.3V
  • ESP could required 300mA peak
Hum... So for RX and Vcc I will use voltage divider or zener.. and for the 300 mA it should be ok as I use my own power supply  with 7805 that could provide 1.5A max...
For the connection, I found many link for example :
here is the current schematic


So let's start and see if a zener regulation with BZXC55C3V3 500mW (with a serial resistor) is possible (see Zener Diode  introduction from M. H. Miller or http://electronics.stackexchange.com/questions/28944/selecting-correct-zener-diode).
With this kind of regulation, the serial resistor is calculated with the max current in the "load" (here 300mA for ESP8266) and the minimum for zener work (I took 10mA) so 310mA. When no more load is required, the execess should be absorb be zener... when nothing is required from the load the ESP 8266 require low current. The wort case is 0 A , the datasheet gives 0,9 mA in standby mode.
So the zener should absorb 309,1mA .... far more than the maximum current (I= P/U) 151mA (Izrm 115mA)
This solution is not suitable.

So as I have LM317, let's use one....
To build a regulation with a LM317 you could use this schematic

and this formula 
Vout=Vref(1+R1/R2)+IadjR2
 
$E=mc^2$

Vref = 1.25
Iadj = 50A



to be continued...


Next step : 
  • serve information  collected : exposing data through REST API on raspberry PI
  • Using arduino interrupt 
  • what if other 433Mhz peripherals exists  ?....  One : how to check that.... Two :change ardess with dip switch WIP


Saturday, February 14, 2015

Raspberry pi adding USB dongle Realtek RTL8188CUS


I received today my Realtek dongle for my Raspberry pi.

To have a reminder. I write this short post.

Recipe

  • Power off raspberry pi
  • Put add your wifi dongle
  • Use lsusb command to see if your peripheral is right detected. Your should see something like

Bus 001 Device 004: ID 0bda:8176 Realtek Semiconductor Corp.
 RTL8188CUS 802.11n WLAN Adapter


Then in /etc/network edit in sudo mode the interfaces file

allow-hotplug
wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-conf etc/${path_to_your_wpa_supplicant.conf}


Then edit your wpa_supplicant.conf. see here for more informations or here. Be carreful when setting up network parameter, that depends of your wifi point authentification (WEP,WPA or WPA2)
network={
     ssid="your_ssid_box_for_example"
     psk="your_password"
     proto=RSN
     key_mgmt=WPA-PSK
     pairwise=CCMP TKIP
     group=CCMP TKIP
 }
At the end shutdown your raspberry, disconnect your previous ethernet conection (if exists). Restart your RPi.
After restart you should have an IP adress for your wlanYY interface (use ifconfig command).

Tuesday, February 10, 2015

Jenkins : duplicate jenkins enviromnent and apply SCM change on every job

Duplicate Continuous integration (Jenkins) enviromnent

Just a reminder to explain and speak about jenkins scripting console.

Our problem is :
  • we have many hundred maven projets
  • each project has its job in jenkins (project choice)
  • when preparing a new release we "branch" all sources in our SCM

question how can we duplicate jenkins environement ?

Cookbook

  • install a new jenkins instance 
  • install in this instance a plugin called Job import plugin
  • use this plugin and import all job from your initial instance
  • Then use the script console  ${host}/${Jenkins_inst_name}/script . This jenkins feature is very powerfull. It's allow to walk through all job and mofify them if needed. In our case we apply this groovy script (I start from this source wiki.jenkins-ci.org/display/JENKINS/Change+Version-Number+in+SVN-path)
import hudson.scm.*
hudsonInstance = hudson.model.Hudson.instance
overrideExistingValues = false
allItems = hudsonInstance.items
allItems.each { job-> println "Name : "+job.name;
if(!(job instanceof hudson.model.ExternalJob)) {
   if (job.scm instanceof SubversionSCM) {
     def newSvnPath = [][]
     println "SCM job : "+job.name;
     job.scm.locations.each{
       println "Scm location : "+it.remote;
       newRemote = it.remote
       newRemote = newRemote.replaceAll("franckys/svn/LOCAL/trunk",
        "franckys/svn/LOCAL/branches/preV2")
       newSvnPath.add(new hudson.scm.SubversionSCM.
        ModuleLocation(newRemote,it.local))
       println "Scm new location : "+newRemote;
     }
     newscm = new hudson.scm.SubversionSCM(newSvnPath,
        job.scm.workspaceUpdater, job.scm.browser,
     job.scm.excludedRegions, job.scm.excludedUsers, job.scm.excludedRevprop, 
        job.scm.excludedCommitMessages, job.scm.includedRegions)
     if (overrideExistingValues){
       job.scm = newscm;
     }
   }
 }
}
If you have interest in script you could have a look at : https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console