Wednesday, March 30, 2016

YellowJacket Arduino with WiShield Wifi (Part 15)

How to Sense the Status of Arduino/Wifi Pins — 
Question: How to check whether the YellowJacket Arduino SPI-CS pin D10 is triggered from normally HIGH to LOW, and how often?
To answer this question, add this code to your sketch Global section
/****** INT1 pin D3 capture CS pin change  **************/
// wire a jumper from CS inputPin D10 to sensePin D3 to catch hardware interrupt
     int watchPin = 10;  // the pin that is being watched
     boolean sensor_status = false;
     int sensePin = 3;   // digital pin 3 int1; int0 pin D2 is used by YJ MRF24 
     int ledPin = 4;   //the digital pin for output to LED display 

void sensorOn() { 
     if (sensor_status != true) { 
          sensor_status = true; 
          Serial.println(F("  >> Sensor Status: Activated >> ")); 
          ledOn(); 
     } 
} 

void sensorOff() { 
     if (sensor_status != false) { 
          sensor_status = false; 
          Serial.println(F("  >> Sensor Status: Cleared >> ")); 
          ledOff(); 
     } 
} 

void ledOn() { 
     digitalWrite(ledPin, HIGH); 
     //Serial.println(F("  >> LED Status: On >> ")); 
} 

void ledOff() { 
     digitalWrite(ledPin, LOW); 
     //Serial.println(F("  >> LED Status: Off >> ")); 
} 
/****** end INT1 pin D3 capture pin change  **************/
Add this code to the sketch setup()
/****** INT1 pin D3 capture pin change  **************/

// Attach interrupt INT1 to pin 3 held normally high through 10K resistor to 3V3
// or use "pinMode(sensePin, INPUT_PULLUP);" for internal pullup resistor
//    Trigger signal (example: D10 is normally HIGH) grounds pin D3 to set sensorOn

attachInterrupt(digitalPinToInterrupt(sensePin), sensorOn, FALLING);

// sensePin senses watchPin immediate state change HIGH to LOW
pinMode(ledPin, OUTPUT);      // sets the digital ledPin as output
pinMode(watchPin, INPUT);     // sets the digital watchPin as input of sense state

sensorOff();
ledOff();

/****** end INT1 pin D3 capture pin change  **************/
Trigger the sensor_status in sketch loop()
/****** INT1 pin D3 capture pin change  **************/

// clear the sensor_status to check for new sensorOn
// Clearing the sensor_status is required here
//    since in the example CS pin D10 was set during the Wifi INIT
//    and we want to check if and when the CS pin changes state

sensorOff();

/****** end INT1 pin D3 capture pin change  **************/
Example Sketch CSpin10 — wire pin D3 (INT1 interrupt) to pin D10 (MRF24 wifi Active). Run the sketch. Mac Wireshark app can be used to watch the network traffic between 10.0.1.56 Arduino and 10.0.1.11 Mac.
/***************************************************
 * CSpin10
 *
 * March 20, 2016
 * This sketch watches CS pin D10 for sensor_status on/off activity
 *
 *    reads a sensor on the Sensor Shield
 *    processes the data
 *    creates a php request
 *    sends the php request to Apache
 *    the php request is submitted to mysql
 *    data element is written to mysql table
 *
 *    The sketch can format the data as int, float, or char array
 *    and submit the request as a char array.
 *
 *    The dtostrf function for converting a float to a char array
 *    will preface the array with a blank for the - sign.
 *    Using an F0.2 format will dispose of leading blanks which
 *    cause errors loadint the data into mysql.
 *
 * Wireshark shows 10.0.1.56 HTTP request:
 *  GET /write_data?value=75.59 HTTP/1.0\r\n
 *    Request Method:  GET
 *    Request URI:  /write_data.php?value=75.79
 *    Request Version:  HTTP/1.0
 *  Host:  Mac_localhost\r\n
 *  \r\n
 *
 * 10.0.1.11 HTTP response:
 *  HTTP/1.1 200 OK\r\n
 *    Request Version:  HTTP/1.1
 *    Status Code:  200
 *    Response Phrase:  OK
 *  Date: Thu, 10 Mar 2016 12:38:14 GMT\r\n
 *  Server: Apache/2.4.10 (Unix) PHP/5.5.20\r\n
 *  X-Powered-By: PHP/5.5.20\r\n
 *  Content-Length: 26\r\n
 *  Connection: close\r\n
 *  Content-Type: text/html\r\n
 *  \r\n
 *  [HTTP response 1/1]
 *  [Time since request: 0.002082000 seconds]
 *  [Request in frame: 247]
 *  Line-based text data: text/html
 *
 *
 *
 ****************************************************/

#include <WiServerIO.h>
//#include "SPI.h"  // Arduino SPI.h not WiShield spi_WS.h

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "Network"
#define WLAN_PASS       "Network_Passcode"

/*---------------------------------------------------------------------------
 *
 * WiServer set up
 *
 */

#define WIRELESS_MODE_INFRA  1
#define WIRELESS_MODE_ADHOC 2

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {10, 0, 1, 56}; // IP address of WiShield
unsigned char gateway_ip[] = {10, 0, 1, 1}; // router or gateway IP address
unsigned char subnet_mask[] = {255, 255, 255, 0}; // subnet mask for the local network
const char ssid[] PROGMEM = {"Network"};   // max 32 bytes
char* myhost_ip = "10.0.1.56";

unsigned char security_type = 3;  // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// WPA/WPA2 passphrase
const char security_passphrase[] PROGMEM = {"Network_Passcode"};  // max 64 characters

// WEP 128-bit keys
// sample HEX keys
const uint8_t wep_keys[] PROGMEM = {  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, // Key 0
                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 1
                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Key 2
                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Key 3
                                   };

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;

unsigned char ssid_len;
unsigned char security_passphrase_len;

//---------------------------------------------------------------------------

/****************************** Feeds ***************************************/
/* ---------------------------------------------------------------------------
*
*  A simple data logger for the Arduino analog pins
*
*/

//#define aref_voltage 3.3// tie 3.3V to ARef
#define aref_voltage 5.0  // default internal 5V to ARef

int photocellPin = 1;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the analog resistor divider

int temperaturePin = 0;   //the analog pin the TMP36's Vout (sense) pin is connected to
//the resolution is 10 mV / degree centigrade with a
//500 mV offset to allow for negative temperatures
int temperatureReading;   // the analog reading from the sensor

/****** INT1 pin D3 capture CS pin change  **************/
// wire jumper from CS inputPin D10 to sensePin D3 to catch hardware interrupt
int watchPin = 10;  // the pin that is being watched

boolean sensor_status = false;
int sensePin = 3;   // digital pin 3 int1; int0 pin D2 is used by YJ MRF24
int ledPin = 4;   //the digital pin for output to LED display

void sensorOn() {
  if (sensor_status != true) {
    sensor_status = true;
    Serial.println(F("  >> Sensor Status: Activated >> "));
    ledOn();
  }
}

void sensorOff() {
  if (sensor_status != false) {
    sensor_status = false;
    Serial.println(F("  >> Sensor Status: Cleared >> "));
    ledOff();
  }
}

void ledOn() {
  digitalWrite(ledPin, HIGH);
  //Serial.println(F("  >> LED Status: On >> "));
}

void ledOff() {
  digitalWrite(ledPin, LOW);
  //Serial.println(F("  >> LED Status: Off >> "));
}
/****** end INT1 pin D3 capture pin change  **************/


char inURL[22] = "/write_data.php?value";
char requestURL[80];
//char data[20];            // char[] array for the converted int or float

float tempF;
int tF;

/*---------------------------------------------------------------------------*/

/*************************** Sketch Code ************************************/

// Function that prints data returned from the server
void printData(char* data, int len) {
  // Note that the data is not null-terminated, may be broken up into smaller packets,
  // and includes the HTTP header.
  while (len-- > 0) {
    Serial.print(*(data++));
  }
}

// Function that assembles URL to send to the server
void myURL() {
  /* ----------------------- data logger ----------------------------------------*/
  // Read data

  photocellReading = analogRead(photocellPin);
  temperatureReading = analogRead(temperaturePin);
  // converting that reading to voltage, which is based off the reference voltage
  float voltage = temperatureReading * aref_voltage / 1024;
  // calculate temperature
  float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
  //                                            //to degrees ((voltage - 500mV) times 100)
  //Serial.print(temperatureC); Serial.println(" degrees C");

  // convert C to Fahrenheit
  float temperatureF = (temperatureC * 9 / 5) + 32;

  tempF = temperatureF; // save alue in global tempF

  double dF = temperatureF;

  Serial.println("... ");
  // Serial.println(""); Serial.print("Light reading = "); Serial.println(photocellReading);
  // the raw analog reading

  // DEBUG the calculated temperatureF to the Serial Monitor
  Serial.print(temperatureF); Serial.println(F(" degrees F"));

  // conversion of int or float to char[] may not be needed, since "WiServer.print (tempF);"
  // displays the same number (83.49) as "dtostrf(temperatureF, 6, 2, data);"
  // which converts float to char[] array (data), f6.2 format but has leading space for - sign
  // do not know how WiServer.print formats to f6.2 by default.

  char data[20];
  //sprintf will convert int to char, but not float to char which requires dtostrf
  dtostrf(dF, 0, 2, data);        // converts float to char[] array (data)
  // f0.2 format forces left justify which deletes any leading spaces which cause problems in mysql
  Serial.print(data); Serial.println(F(" char degrees F"));

  tF = (int)temperatureF;
  Serial.print(tF); Serial.println(F(" int degrees F"));

  char data1[20];
  sprintf(data1, "%i", tF); // converts int to char[] array (data)
  Serial.print(data1); Serial.println(F(" data[] int degrees F"));

  /* -------------------End Data Logger ----------------------------------------*/

  // Send an int value to mysql works reliably
  //sprintf(requestURL, "%s=%i", inURL, tF); // appends int number; this works

  // Send an int value as a char[] to mysql works reliably
  //sprintf(requestURL, "%s=%s", inURL, data1); // appends char number.

  // Send a double value as a char[] to mysql works reliably with f0.1 format
  sprintf(requestURL, "%s=%s", inURL, data); // appends dtostrf char double number.

  Serial.print(" requestURL= "); Serial.println(requestURL);
}

uint8_t request_ip[] = {10, 0, 1, 11}; // IP Address for requested server Mac
char* myhost = "Mac_localhost";

// A request that gets a file from server at request_ip
GETrequest getMyRequest(request_ip, 80, myhost, requestURL);

void setup() {
  Serial.begin(115200);
  delay(10);

  /****** INT1 pin D3 capture pin change  **************/
  // Attach interrupt INT1 to pin 3 held normally high through 10K resistor to 3V3
  // or use "pinMode(sensePin, INPUT_PULLUP);" for internal pullup resistor
  //    Trigger signal (example: D10 is normally HIGH) grounds pin D3 to set sensorOn
  attachInterrupt(digitalPinToInterrupt(sensePin), sensorOn, FALLING);
  pinMode(sensePin, INPUT_PULLUP);
  // sensePin senses watchPin immediate state change HIGH to LOW
  pinMode(ledPin, OUTPUT);      // sets the digital ledPin as output
  pinMode(watchPin, INPUT);      // sets the digital watchPin as input of sense state
  sensorOff();
  ledOff();
  /****** end INT1 pin D3 capture pin change  **************/

  // Connect to WiFi access point.
  Serial.println();
  Serial.print(F("Init WiServer Client to External IO Server: "));
  Serial.println(myhost);

  // Initialize WiServer and have it use the sendMyPage function to serve pages
  // WiServer.init(sendMyPage);
  WiServer.init(NULL);

  // Ask WiServer to generate log messages (optional)
  WiServer.enableVerboseMode(true);

  // Have the processData function called when data is returned by the server
  getMyRequest.setReturnFunc(printData);

  Serial.println (">>> Send data on 30 sec intervals... ");
  Serial.println (" ");
}

uint32_t x = 0;
// Time (in millis) when the data should be retrieved
unsigned long tempTime = millis();
unsigned long updateTime = tempTime;
unsigned long waitTime = 1000UL * 30UL ; // 30 second cycle

void loop() {

  tempTime = millis();

  /****** INT1 pin D3 capture pin change  **************/
  // clear the sensor_status to check for new sensorOn
  // Clearing the sensor_status is required here
  //    since in the example CS pin D10 was set during the Wifi INIT
  //    and we want to check if and when the CS pin changes state
  sensorOff();
  /****** end INT1 pin D3 capture pin change  **************/


  // Check if it's time to get an update
  if (tempTime >= updateTime) {

    myURL();

    Serial.println (" "); // space to display

    getMyRequest.submit();
    Serial.println (" "); // space to display
    /* DEBUG
       Serial.println (" ");
       Serial.print (" >> If 1: millis() = ");
       Serial.print ( tempTime );
       Serial.print ("  updateTime = ");
       Serial.print ( updateTime );
       Serial.print ("  waitTime = ");
       Serial.println ( waitTime );
    End DEBUG */
    // Get another update 30 seconds from now


    updateTime += waitTime;
    /* DEBUG
        Serial.print (" Revised updateTime = ");
        Serial.println ( updateTime );
    End DEBUG */
  }

  // Run WiServer
  WiServer.server_task();

  delay(100);
}
Sketch CSpin10 Serial Monitor output: The sensor_status of CS pin D10 toggles frequently when needing to transmit data,  controlled by the MRF24 Wifi board.
>> Sensor Status: Cleared >>
>> Sensor Status: Activated >>
>> Sensor Status: Cleared >>
RX 214 bytes from Mac_localhost
HTTP/1.1 200 OK
Date: Tue, 01 Mar 2016 19:04:44 GMT
Server: Apache/2.4.10 (Unix) PHP/5.5.20
X-Powered-By: PHP/5.5.20
Content-Length: 27
Connection: close
Content-Type: text/html
Entered data successfully
>> Sensor Status: Activated >>
>> Sensor Status: Cleared >>
Ended connection with Mac_localhost
>> Sensor Status: Activated >>
>> Sensor Status: Cleared >>
>> Sensor Status: Activated >>
>> Sensor Status: Cleared >>
(Mar 30, 2016)

No comments:

Post a Comment