spark/core-firmware — pull request #70 by davids5 (2014-01-30 21:30:28+00:00)
Title: TCP/UDP streamlining and Off load the cc3000 faster

Fixes for peek it is now non-destructive
TCP/UDP streamlining (less code data)
Buffer size set back to 512 - ( the thing flies with no communication delays needed in the code )
The TCP code will Off load the cc3000 faster freeing up buffers.

The test code is below both server side and spark for UDP and TCP
----------------------------------
TCP test code (not pretty) php
----------------------------------

----------------------------------
TCP test code (not pretty)
----------------------------------
/**
******************************************************************************
* @file application.cpp
* @authors Satish Nair, Zachary Crockett and Mohit Bhoite
* @version V1.0.0
* @date 05-November-2013
* @brief Tinker application
******************************************************************************
Copyright (c) 2013 Spark Labs, Inc. All rights reserved.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see .
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "application.h"
extern "C" void debug(const char *p);
void debug(int v);
void debug_time(const char *p);

#define RENEW_INTERVAL 5*1000 // 30 secs
#define RETRY_INTERVAL 5*1000 // 10 secs
#define RESPONSE_INTERVAL 1*1000 // 1 sec
#define LET_IT_FILL_INTERVAL 3*1000 // 1 sec

TCPClient client;
char server[] = "nscdg.com";

// IO
int led = D2;

// Globals
volatile int state = 0;
volatile int wait = 0;
volatile int loopwait = 10;

volatile int tries = 0;
volatile int store = 0;
volatile int hash = 0;

volatile char command[32];
volatile int command_i=0;

void setup1()
{

debug("Thermometer sketch");

pinMode(led, OUTPUT);
// Button resistorless
state = 0;
wait = RETRY_INTERVAL;

// Connecting
}
uint8_t buffer[TCPCLIENT_BUF_MAX_SIZE+1]; // for EOT
int loops = 0;
int total = 0;
void loop1()
{

delay(1);
switch(state){
case 0:
// Waiting for next time
wait-=10;
if(wait<0){
wait = 0;
state = 1;
}
break;
case 1:
// Connecting
debug_time("connecting");
total = 0;
if (client.connect(server, 80)){
debug_time("connected");
state = 2;
}else{
debug_time("connection failed state 1");
wait = RETRY_INTERVAL;
state = 0;
}
break;
case 2:
// Requesting
if(client.connected()){
debug_time (" Send");
client.println("GET /t.php HTTP/1.0\r\n\r\n");
debug_time (" Sent");
wait = LET_IT_FILL_INTERVAL;
state = -3;
}else{
debug("connection lost state 2");
wait = RETRY_INTERVAL;
state = 0;
}
break;

case -3:
if (client.available()) {
debug_time (" Ready");
state = 3;
}
wait--;
if(wait<0){
wait = 0;
state = 4;
}
break;
case 3:
// Receiving
if(client.connected()){
int count = client.available();
debug(count);
debug (" Bytes Avail");
if (count > 0)
{
loops = 0;
// Print response to serial
count = client.read(buffer, arraySize(buffer));
buffer[count] ='\0';
char *p = strstr((const char *)buffer,"0.1.2.3");
if (p)
{
total = -(p-(char*)buffer);
}
total += count;
debug(count);
debug (" Bytes Read");
debug ((const char*)buffer);
} else {
delay(100);
if (++loops > 2) {
wait = 1;
state = 4;
}
}
}else{
// We lost connection
debug("connection lost state 3");
wait = RETRY_INTERVAL;
state = 0;
}
break;
case 4:
// Disconnecting
if(client.connected()){
debug(total);
debug (" total Bytes Read");
client.stop();
debug_time("connection closed state 4");
wait = RENEW_INTERVAL;
state = 0;
}else{
debug("connection closed by server state 4");
wait = RENEW_INTERVAL;
state = 0;
}
break;
}
}

/* Function prototypes -------------------------------------------------------*/
int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int tinkerAnalogRead(String pin);
int tinkerAnalogWrite(String command);

/* This function is called once at start up ----------------------------------*/
void setup()
{
//Setup the Tinker application here
// Serial1.begin(115200);
//Register all the Tinker functions

setup1();
Spark.function("digitalread", tinkerDigitalRead);
Spark.function("digitalwrite", tinkerDigitalWrite);

Spark.function("analogread", tinkerAnalogRead);
Spark.function("analogwrite", tinkerAnalogWrite);

}

/* This function loops forever --------------------------------------------*/

void debug_time(const char *p)
{
Serial1.print(millis());
Serial1.print(" ");
Serial1.println(p);
}
void debug(const char *p)
{
static boolean once = false;
if (!once)
{
once = true;
Serial1.begin(115200);
}

//prints time since program started
// Serial1.print(millis());
// Serial1.print(" ");
Serial1.println(p);
}

void debug(int v)
{
Serial1.print(v);
}

void loop()
{
static int count = 0;
if (count) {
count+= 5000;
Serial1.print(count);
delay(count);
debug("end");
}
loop1();
//This will run in a loop
}

/*******************************************************************************
* Function Name : tinkerDigitalRead
* Description : Reads the digital value of a given pin
* Input : Pin
* Output : None.
* Return : Value of the pin (0 or 1) in INT type
Returns a negative number on failure
*******************************************************************************/
int tinkerDigitalRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(pin.startsWith("D"))
{
pinMode(pinNumber, INPUT_PULLDOWN);
return digitalRead(pinNumber);
}
else if (pin.startsWith("A"))
{
pinMode(pinNumber+10, INPUT_PULLDOWN);
return digitalRead(pinNumber+10);
}
return -2;
}

/*******************************************************************************
* Function Name : tinkerDigitalWrite
* Description : Sets the specified pin HIGH or LOW
* Input : Pin and value
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerDigitalWrite(String command)
{
bool value = 0;
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(command.substring(3,7) == "HIGH") value = 1;
else if(command.substring(3,6) == "LOW") value = 0;
else return -2;

if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, value);
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
digitalWrite(pinNumber+10, value);
return 1;
}
else return -3;
}

/*******************************************************************************
* Function Name : tinkerAnalogRead
* Description : Reads the analog value of a pin
* Input : Pin
* Output : None.
* Return : Returns the analog value in INT type (0 to 4095)
Returns a negative number on failure
*******************************************************************************/
int tinkerAnalogRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(pin.startsWith("D"))
{
pinMode(pinNumber, INPUT);
return analogRead(pinNumber);
}
else if (pin.startsWith("A"))
{
pinMode(pinNumber+10, INPUT);
return analogRead(pinNumber+10);
}
return -2;
}

/*******************************************************************************
* Function Name : tinkerAnalogWrite
* Description : Writes an analog value (PWM) to the specified pin
* Input : Pin and Value (0 to 255)
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerAnalogWrite(String command)
{
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

String value = command.substring(3);

if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
analogWrite(pinNumber, value.toInt());
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
analogWrite(pinNumber+10, value.toInt());
return 1;
}
else return -2;
}
-----------------------------------------------
UPD test code (not pretty) Node
----------------------------------------------
node
var PORT = 8738;
var HOST = '10.10.0.186';

function send(len)
{
var dgram = require('dgram');
var message = new Buffer('0.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.37.38.39.40.41.42.43.44.45.46.47.48.49.50.51.52.53.54.55.56.57.58.59.60.61.62.63.64.65.66.67.68.69.70.71.72.73.74.75.76.77.78.79.80.81.82.83.84.85.86.87.88.89.90.91.92.93.94.95.96.97.98.99.100.101.102.103.104.105.106.107.108.109.110.111.112.113.114.115.116.117.118.119.120.121.122.123.124.125.126.127.128.129.130.131.132.133.134.135.136.137.138.139.140.141.142.143.144.145.146.147.148.149.150.151.152.153.154.155.156.157.158.159.160.161.162.163.164.165.166.167.168.169.170.171.172.173.174.175.176.177.178.179.180.181.182.183.184.185.186.187.188.189.190.191.192.193.194.195.196.197.198.199.200.201.202.203.204.205.206.207.208.209.210.211.212.213.214.215.216.217.218.219.220.221.222.223.224.225.226.227.228.229.230.231.232.233.234.235.236.237.238.239.240.241.242.243.244.245.246.247.248.249.250.251.252.253.254.255.256.257.258.259.260.261.262.263.264.265.266.267.268.269.270.271.272.273.274.275.276.277.278.279.280.281.282.283.284.285.286.287.288.289.290.291.292.293.294.295.296.297.298.299.300.301.302.303.304.305.306.307.308.309.310.311.312.313.314.315.316.317.318.319.320.321.322.323.324.325.326.327.328.329.330.331.332.333.334.335.336.337.338.339.340.341.342.343.344.345.346.347.348.349.350.351.352.353.354.355.356.357.358.359.360.361.362.363.364.365.366.367.368.369.370.371.372.373.374.375.376.377.378.379.380.381.382.383.384.385.386.387.388.389.390.391.392.393.394.395.396.397.398.399.400.401.402.403.404.405.406.407.408.409.410.411.412.413.414.415.416.417.418.419.420.421.422.423.424.425.426.427.428.429.430.431.432.433.434.435.436.437.438.439.440.441.442.443.444.445.446.447.448.449.450.451.452.453.454.455.456.457.458.459.460.461.462.463.464.465.466.467.468.469.470.471.472.473.474.475.476.477.478.479.480.481.482.483.484.485.486.487.488.489.490.491.492.493.494.495.496.497.498.499.500.501.502.503.504.505.506.507.508.509.510.511.512.513.514.515.516.517.518.519.520.521.522.523.524.525.526.527.528.529.530.531.532.533.534.535.536.537.538.539.540.541.542.543.544.545.546.547.548.549.550.551.552.553.554.555.556.557.558.559.560.561.562.563.564.565.566.567.568.569.570.571.572.573.574.575.576.577.578.579.580.581.582.583.584.585.586.587.588.589.590.591.592.593.594.595.596.597.598.599.600.601.602.603.604.605.606.607.608.609.610.611.612.613.614.615.616.617.618.619.620.621.622.623.624.625.626.627.628.629.630.631.632.633.634.635.636.637.638.639.640.641.642.643.644.645.646.647.648.649.650.651.652.653.654.655.656.657.658.659.660.661.662.663.664.665.666.667.668.669.670.671.672.673.674.675.676.677.678.679.680.681.682.683.684.685.686.687.688.689.690.691.692.693.694.695.696.697.698.699.700.701.702.703.704.705.706.707.708.709.710.711.712.713.714.715.716.717.718.719.720.721.722.723.724.725.726.727.728.729.730.731.732.733.734.735.736.737.738.739.740.741.742.743.744.745.746.747.748.749.750.751.752.753.754.755.756.757.758.759.760.761.762.763.764.765.766.767.768.769.770.771.772.773.774.775.776.777.778.779.780.781.782.783.784.785.786.787.788.789.790.791.792.793.794.795.796.797.798.799.800.801.802.803.804.805.806.807.808.809.810.811.812.813.814.815.816.817.818.819.820.821.822.823.824.825.826.827.828.829.830.831.832.833.834.835.836.837.838.839.840.841.842.843.844.845.846.847.848.849.850.851.852.853.854.855.856.857.858.859.860.861.862.863.864.865.866.867.868.869.870.871.872.873.874.875.876.877.878.879.880.881.882.883.884.885.886.887.888.889.890.891.892.893.894.895.896.897.898.899.900.901.902.903.904.905.906.907.908.909.910.911.912.913.914.915.916.917.918.919.920.921.922.923.924.925.926.927.928.929.930.931.932.933.934.935.936.937.938.939.940.941.942.943.944.945.946.947.948.949.950.951.952.953.954.955.956.957.958.959.960.961.962.963.964.965.966.967.968.969.970.971.972.973.974.975.976.977.978.979.980.981.982.983.984.985.986.987.988.989.990.991.992.993.994.995.996.997.998.999.'.substring(0,i));

var client = dgram.createSocket('udp4');
client.send(message, 0, message.length, PORT, HOST, function(err, bytes) {
if (err) throw err;
console.log(i + ' UDP message sent to ' + HOST +':'+ PORT);
client.close();
});
}

var i = 100;
setInterval(function() {
send(i+=10);
}, 1000);

-----------------------------------------------
UPD test code (not pretty) Application
----------------------------------------------
/**
******************************************************************************
* @file application.cpp
* @authors Satish Nair, Zachary Crockett and Mohit Bhoite
* @version V1.0.0
* @date 05-November-2013
* @brief Tinker application
******************************************************************************
Copyright (c) 2013 Spark Labs, Inc. All rights reserved.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, either
version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see .
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "application.h"
extern "C" void debug(const char *p);
void debug(int v);
void debug_time(const char *p);

#define RENEW_INTERVAL 5*1000 // 30 secs
#define RETRY_INTERVAL 5*1000 // 10 secs
#define RESPONSE_INTERVAL 1*1000 // 1 sec
#define LET_IT_FILL_INTERVAL 3*1000 // 1 sec

TCPClient client;
char server[] = "nscdg.com";

// IO
int led = D2;

// Globals
volatile int state = 0;
volatile int wait = 0;
volatile int loopwait = 10;

volatile int tries = 0;
volatile int store = 0;
volatile int hash = 0;

volatile char command[32];
volatile int command_i=0;

UDP Udp;
void setup1()
{

debug("Thermometer sketch");

pinMode(led, OUTPUT);
// Button resistorless
state = 0;
wait = RETRY_INTERVAL;
Udp.begin(8738);
// Connecting
}
uint8_t buffer[TCPCLIENT_BUF_MAX_SIZE+1]; // for EOT
int loops = 0;
int total = 0;
void loop1()
{
delay(1);
if (++loops == 100) {
loops = 0;
debug_time("parsePacket");
int packetSize = Udp.parsePacket();
debug(packetSize);
debug(" Received packet of size ");
if(packetSize > 0)
{
debug_time("read");
int count = Udp.read(buffer,sizeof(buffer));
buffer[count] = '\0';
total += count;
debug(count);
debug (" Bytes Read");
debug ((const char*)buffer);
}
}
}

/* Function prototypes -------------------------------------------------------*/
int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int tinkerAnalogRead(String pin);
int tinkerAnalogWrite(String command);

/* This function is called once at start up ----------------------------------*/
void setup()
{
//Setup the Tinker application here
// Serial1.begin(115200);
//Register all the Tinker functions

setup1();
Spark.function("digitalread", tinkerDigitalRead);
Spark.function("digitalwrite", tinkerDigitalWrite);

Spark.function("analogread", tinkerAnalogRead);
Spark.function("analogwrite", tinkerAnalogWrite);

}

/* This function loops forever --------------------------------------------*/

void debug_time(const char *p)
{
Serial1.print(millis());
Serial1.print(" ");
Serial1.println(p);
}
void debug(const char *p)
{
static boolean once = false;
if (!once)
{
once = true;
Serial1.begin(115200);
}

//prints time since program started
// Serial1.print(millis());
// Serial1.print(" ");
Serial1.println(p);
}

void debug(int v)
{
Serial1.print(v);
}

void loop()
{
static int count = 0;
if (count) {
count+= 5000;
Serial1.print(count);
delay(count);
debug("end");
}
loop1();
//This will run in a loop
}

/*******************************************************************************
* Function Name : tinkerDigitalRead
* Description : Reads the digital value of a given pin
* Input : Pin
* Output : None.
* Return : Value of the pin (0 or 1) in INT type
Returns a negative number on failure
*******************************************************************************/
int tinkerDigitalRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(pin.startsWith("D"))
{
pinMode(pinNumber, INPUT_PULLDOWN);
return digitalRead(pinNumber);
}
else if (pin.startsWith("A"))
{
pinMode(pinNumber+10, INPUT_PULLDOWN);
return digitalRead(pinNumber+10);
}
return -2;
}

/*******************************************************************************
* Function Name : tinkerDigitalWrite
* Description : Sets the specified pin HIGH or LOW
* Input : Pin and value
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerDigitalWrite(String command)
{
bool value = 0;
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(command.substring(3,7) == "HIGH") value = 1;
else if(command.substring(3,6) == "LOW") value = 0;
else return -2;

if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
digitalWrite(pinNumber, value);
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
digitalWrite(pinNumber+10, value);
return 1;
}
else return -3;
}

/*******************************************************************************
* Function Name : tinkerAnalogRead
* Description : Reads the analog value of a pin
* Input : Pin
* Output : None.
* Return : Returns the analog value in INT type (0 to 4095)
Returns a negative number on failure
*******************************************************************************/
int tinkerAnalogRead(String pin)
{
//convert ascii to integer
int pinNumber = pin.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

if(pin.startsWith("D"))
{
pinMode(pinNumber, INPUT);
return analogRead(pinNumber);
}
else if (pin.startsWith("A"))
{
pinMode(pinNumber+10, INPUT);
return analogRead(pinNumber+10);
}
return -2;
}

/*******************************************************************************
* Function Name : tinkerAnalogWrite
* Description : Writes an analog value (PWM) to the specified pin
* Input : Pin and Value (0 to 255)
* Output : None.
* Return : 1 on success and a negative number on failure
*******************************************************************************/
int tinkerAnalogWrite(String command)
{
//convert ascii to integer
int pinNumber = command.charAt(1) - '0';
//Sanity check to see if the pin numbers are within limits
if (pinNumber< 0 || pinNumber >7) return -1;

String value = command.substring(3);

if(command.startsWith("D"))
{
pinMode(pinNumber, OUTPUT);
analogWrite(pinNumber, value.toInt());
return 1;
}
else if(command.startsWith("A"))
{
pinMode(pinNumber+10, OUTPUT);
analogWrite(pinNumber+10, value.toInt());
return 1;
}
else return -2;
}