Skip to content

Instantly share code, notes, and snippets.

@vitiral
Last active August 29, 2015 14:05
Show Gist options
  • Save vitiral/72f8af081453c0e47e88 to your computer and use it in GitHub Desktop.
Save vitiral/72f8af081453c0e47e88 to your computer and use it in GitHub Desktop.
This code gets over 12 Hz transfer rates on the spark core (without any delays or hangs)
/**
* Better strncpy
* Example code:
* char buf[100];
* uint16_t len = 100;
* char *place = buf;
* len = bstrncpy(&place, "hello\n", len);
* len = bstrncpy(&place, "another hi\n", len);
* input:
* char **destination -- pointer to the buffer where you want the text.
* The location WILL be altered to the end of the character array.
* char *source -- character array to copy to destination
* len -- length of the array (remaining)
*
* This function ensures that the last character is a 0 -- no matter what.
*
* returns the remaining length of the array (based on the input len)
**/
#include "allduino.h"
uint16_t bstrncpy(char **destination, const char *source, uint16_t len){
uint16_t n;
for(n = 0; (n < len - 1) and (source[n] != 0); n++){
(*destination)[n] = source[n];
}
(*destination)[n] = 0;
(*destination) += n;
return len - n;
}
char *d2strf (double val, signed char width, unsigned char prec, char *sout) {
char fmt[20];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(sout, fmt, val);
return sout;
}
#ifndef __allduino_h
#define __allduino_h
// General include for all files.
// has some basic macros and includes proper arduino libraries
//
#ifdef SPARK
#include <application.h>
#elif (ARDUINO >= 100)
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#endif
#ifdef SPARK
#define ANALOG_MAX 4095
#define LED_PIN 7
#define NAN -1
#else
#define ANALOG_MAX 1023
#define LED_PIN 13
#endif
#define TIME_SINCE(time) ((uint16_t)(millis() - (time)))
#define RUN_ONLY_EVERY(time) \
static uint16_t start = millis() - ((time) + 10); \
if((uint16_t)(millis() - start) < (time)) \
return; \
start = millis();
#define HEARTBEAT() \
static uint8_t _HB_led = 2; \
static uint16_t _HB_start = millis() - ((1000) + 10); \
if((uint16_t)(millis() - _HB_start) > (1000)) { \
if(_HB_led == 2){_HB_led=1;pinMode(LED_PIN, OUTPUT);} \
_HB_start = millis(); \
digitalWrite(LED_PIN, _HB_led); \
_HB_led = 1 - _HB_led; \
}
extern char* itoa(int a, char* buffer, unsigned char radix);
uint16_t bstrncpy(char **destination, const char *source, uint16_t len);
char *d2strf (double val, signed char width, unsigned char prec, char *sout);
#endif
#include "allduino.h"
#include <stdlib.h>
// you fill this in
byte server[] =
char *endpoint =
char *server_str =
enum IO_STATUS{
IO_FREE,
IO_SENDING
};
struct ClientStruct{
TCPClient client;
unsigned char state = IO_FREE; // : 1;
unsigned int last_ran;
};
struct ClientStruct client;
// code for handling sending out data.
// returns whether port is available to send data
#define MIN_COM_PERIOD 80
uint8_t manage_connection(struct ClientStruct *cl){
if(cl->state == IO_SENDING){
if(cl->client.connected() == false){
// we are done sending last message
cl->state = IO_FREE;
}
else{
if(TIME_SINCE(cl->last_ran) > MIN_COM_PERIOD) return true;
return false;
}
}
if(cl->state == IO_FREE){
if(cl->client.connected()){
return true;
}
return cl->client.connect(server, port);
}
return false;
}
#define REQUEST_LEN 800
int8_t send_to_tcp(struct ClientStruct *cl, char *message, uint16_t len){
uint32_t start;
char small_buf[10];
char request[REQUEST_LEN];
char *place = request;
uint16_t buf_len = REQUEST_LEN;
if(not manage_connection(cl)){
return false;
}
buf_len = bstrncpy(&place, "POST ", buf_len);
buf_len = bstrncpy(&place, endpoint, buf_len);
buf_len = bstrncpy(&place, " HTTP/1.1\r\nHost: ", buf_len);
buf_len = bstrncpy(&place, server_str, buf_len);
buf_len = bstrncpy(&place, "\r\nContent-Length: ", buf_len);
itoa(len, small_buf, 10);
buf_len = bstrncpy(&place, small_buf, buf_len);
buf_len = bstrncpy(&place, "\r\nContent-Type: application/json\r\n", buf_len);
buf_len = bstrncpy(&place, "Connection: keep-alive\r\n", buf_len);
buf_len = bstrncpy(&place, "\r\n", buf_len);
buf_len = bstrncpy(&place, message, buf_len);
buf_len = bstrncpy(&place, "\r\n", buf_len);
if(buf_len == 0){
Serial.println("BUF_LEN not enough!");
return -1;
}
/*start = micros();*/
cl->client.write((const uint8_t *)request, REQUEST_LEN - buf_len);
/*start = micros() - start;*/
/*if(start > 600){*/
/*Serial.println(start);*/
/*}*/
cl->last_ran = millis();
cl->state = IO_SENDING;
return true;
}
void setup(){
Serial.begin(115200);
Spark.disconnect();
}
void thread_nio(){
char message[] = "{\"hi\":\"from spark\", \"lots\":{\"lotsOData\":[1,2,3,200,234,234,234,25,223,234,25234,23,234,2]}}";
send_to_tcp(&client, message, strlen(message));
}
void loop(){
HEARTBEAT();
thread_nio();
// flush output. I've had bad luck with using client.flush()
while(client.client.available()){
client.client.read();
/*Serial.write(client.client.read());*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment