The indoor unit

Post date: Feb 13, 2016 11:32:21 AM

The indoor unit is composed of the arduino wifi shield and the DFR Prototype board stacked on top of arduino uno.

The prototype board host the power supply and voltage regulation circuit and the headers connector to connect the 3DR radio transmitter, the Sharp dust sensor and it's components and the 3 micro servo output.

Pin assignment:

Description:

Power:

the device is powered by 12V 1A wall mart with the ground attached to arduino and circuit gnd and the 12Vdc to the arduino Vin.

The servo are powered via a 5V regulator 7805. and the radio by a 3.3 V L4931.

I don't want to use the arduino power output to powered the radio. The radio can drain up to 200ma and i don't want to push through the arduino.

Same thing for the servos they can drain quite a bit of current.

I took the diagram from the datasheet to make the 3.3V and 5V DC power.

Indoor sampling:

The same method as my previous project Dust and particles monitoring with Sharp GP2Y1010AU0F is used to sample the indoor dust sensor.

The data sample are stored in a 100 samples array and and an average reading of the 100 samples is returned from the function.

This dust density is averaged again by the number of samples taken in between two display.The time in between display is setup by a variable. 3s by default.

Outdoor sensor reception and decoding:

The receiver is connected to the software serial pin on the arduino ( pin2 and pin14 or A0). i just need to read the stream of char received by the software serial and concatenate it into a string.

The frame of character send by the remote sensor is like this: |Value|'\n'. where value is the string representation of integer from 0 to 550.

The character "|" is used as separator and the character "'\n'" is used as line separator.

to decode the string and extract the value i'm using the .substring() function and .indexof() function,

it can be done in two lines of code.

SremoteDust=remoteSensor.substring(remoteSensor.indexOf('|')+1,remoteSensor.indexOf('|',remoteSensor.indexOf('|')+1));

remoteDust=SremoteDust.toInt();

Display with the servo:

Every 3s i want to print out the Indoor/outdoor sensor value and the average dust density for 24h to the 3 servos.

The servos are going to dsiplay the reading on 180° semi circle.

The dust density value can go form 0 to 550μ gram/m3. that's giving us a resolution of 3.05μ gram per 1°.

to drive and turn the servo in degrees, i'm using the servo library and create 3 servo client object.

example:

servo3.write(map(dustDensityAvg/indexDustDensity,0,540,0,180));

just need to invert 0 and 180 to have the servo rotating in opposite direction.

I notice that if i keep the servo attached to the client, the servo are always buzing like if they want to turn. it's little bit noisy. to avoid that i attached and detach the servo prior and after every .write code to a servo. doing that i must give enough time to the servo to turn before detaching the client. each step take 15ms according the datasheet.

after each write command to a servo the code must pause for 15ms*number° of rotation.

delay (abs(map(remoteDustAvg/indexRemoteDust,0,540,180,0)-lastRemoteDustAvg)*15);

Posting data to the web server:

Every minute the data are send to a mysql database by using http form posted to a php page hosted on an apache 2 web server.

the php page is hosted on my apache2 server under /dustdensity/add.php

the post request must be formatted as:

"POST /dustdensity/add.php HTTP/1.1" client.print("Host:")serverName

Content-Type: application/x-www-form-urlencoded"

Content-Length:Content-Length

data"

which can be done with the following code:

if (client.connect(serverName,80)) {

client.println("POST /dustdensity/add.php HTTP/1.1");

client.print("Host:");

client.println(serverName);

client.println("Content-Type: application/x-www-form-urlencoded");

client.print("Content-Length: ");

client.println(data.length());

client.println();

client.print(data);

client.flush();

client.stop(); // DISCONNECT FROM THE SERVER

}

The variable data contain a sting "indoor=" + String(dustDensity)+"&outdoor="+String(remoteDust)

it's exactly like entering the following address in the navigation bar of your browser:

http://your.server.com/dustdensity/add.php?indoor=859&outdoor=42&bat=72&sol=64

Getting the data from the web server:

every minute the arduino is requesting data from the web server to gather the average dust density for the last 24h.

The http get request must be formatted as following:

GET /dustdensity/getavg.php HTTP/1.1

Host:serverName

User-Agent: ArduinoWiFi/1.1

Connection: close

which can be done with the following code:

client.println("GET /dustdensity/getavg.php HTTP/1.1");

client.print("Host:");

client.println(serverName);

client.println("User-Agent: ArduinoWiFi/1.1");

client.println("Connection: close");

client.println();

the response from the web server should look like this:

HTTP/1.1 200 OK

Date: Wed, 21 Nov 2012 22:47:21 GMT

Server: Apache

Vary: Accept-Encoding

Connection: close

Content-Type: text/html

[{"AVG(Outdoor)":"16.8348","AVG(Indoor)":"22.2942"}]

where [{"AVG(Outdoor)":"16.8348","AVG(Indoor)":"22.2942"}] contain the data to be extracted.

To decode the AVG(Outdoor) value from the string, i use the same method as above with .substring() function and .indexof() function,

dustAvg.substring(dustAvg.lastIndexOf("[{\"AVG(Outdoor)\":\"")+18,dustAvg.indexOf("\",\""))).toInt()

Schematic:

components:

Code:

Resources available after compilation:

Sketch uses 21,414 bytes (66%) of program storage space. Maximum is 32,256 bytes.

Global variables use 1,294 bytes (63%) of dynamic memory, leaving 754 bytes for local variables. Maximum is 2,048 bytes.

Connecting the WifiShield to the network and posting/getting data from a webserver. <<<<<Previous------Next>>>>>>Servo display