I did not find an updated version of the AF_XPort for the Arduino 1.0.x versions.
So I took all my science (not much in fact) and modified the code of AF_XPort.cpp file to use SoftwareSerial instead of the old librairies ... surprised to me, it was not difficult and 5mn later (yes, I used vi to edit the file) it built successfully. It was too cool to be true ...
Since then, I am fighting like hell to have another output than "Timeout on reset".
I am using the same piece of code I used to have back on arduino-022 and which was working fine ... using the regular adafruit code of AF_XPort.
So, here is the code:
Code: Select all
#include <avr/io.h>
#include "Arduino.h"
#include "SoftwareSerial.h"
#include "AF_XPort.h"
SoftwareSerial xportserial(2,3); // we dont know the pins yet
AF_XPort::AF_XPort(uint8_t rx, uint8_t tx, uint8_t reset, uint8_t dtr, uint8_t rts, uint8_t cts) {
rxpin = rx;
txpin = tx;
resetpin = reset;
if (resetpin) {
pinMode(resetpin, OUTPUT);
digitalWrite(resetpin, HIGH);
}
dtrpin = dtr;
rtspin = rts;
ctspin = cts;
if (ctspin) {
digitalWrite(ctspin, HIGH);
pinMode(ctspin, OUTPUT);
}
}
void AF_XPort::begin(uint16_t b) {
//xportserial.setTX(rxpin);
//xportserial.setRX(txpin);
xportserial = SoftwareSerial(rxpin,txpin);
xportserial.begin(b);
}
uint8_t AF_XPort::reset(void) {
char d;
if (resetpin) {
digitalWrite(resetpin, LOW);
delay(50);
digitalWrite(resetpin, HIGH);
}
// wait for 'D' for disconnected
if (serialavail_timeout(5000)) { // 3 second timeout
d = xportserial.read();
//Serial.print("Read: "); Serial.print(d, HEX);
if (d != 'D'){
return ERROR_BADRESP;
} else {
return 0;
}
}
return ERROR_TIMEDOUT;
}
uint8_t AF_XPort::disconnected(void) {
if (dtrpin != 0) {
return digitalRead(dtrpin);
}
return 0;
}
uint8_t AF_XPort::connect(char *ipaddr, long port) {
char ret;
xportserial.print('C');
xportserial.print(ipaddr);
xportserial.print('/');
xportserial.println(port);
// wait for 'C'
if (serialavail_timeout(3000)) { // 3 second timeout
ret = xportserial.read();
//Serial.print("Read: "); Serial.print(d, HEX);
if (ret != 'C') {
return ERROR_BADRESP;
}
} else {
return ERROR_TIMEDOUT;
}
return 0;
}
// check to see what data is available from the xport
uint8_t AF_XPort::serialavail_timeout(int timeout) { // in ms
while (timeout) {
if (xportserial.available()) {
if (ctspin) { // we read some stuff, time to stop!
digitalWrite(ctspin, HIGH);
}
return 1;
}
// nothing in the queue, tell it to send something
if (ctspin) {
digitalWrite(ctspin, LOW);
}
timeout -= 1;
delay(1);
}
if (ctspin) { // we may need to process some stuff, so stop now
digitalWrite(ctspin, HIGH);
}
return 0;
}
uint8_t AF_XPort::readline_timeout(char *buff, uint8_t maxlen, int timeout) {
uint8_t idx;
char c;
for (idx=0; idx < maxlen; idx++) {
buff[idx] = 0;
if (serialavail_timeout(timeout)) {
c = xportserial.read();
//Serial.print(c); // debugging
if (c == '\n') {
return idx;
} else {
buff[idx] = c;
}
} else {
// timedout!
break;
}
}
return idx;
}
// clear out any extra data
void AF_XPort::flush(int timeout) {
while (serialavail_timeout(timeout)) {
xportserial.read();
}
}
// on direct+ and xport's we can toggle a line to disconnect
void AF_XPort::disconnect() {
/* digitalWrite(XPORT_DISCONN, LOW);
delay(20);
digitalWrite(XPORT_DISCONN, HIGH);*/
}
// print a string from Flash, saves lots of RAM space!
void AF_XPort::ROM_print(const char *pSTR) {
uint16_t i;
for (i = 0; pgm_read_byte(&pSTR[i]); i++) {
xportserial.print(pgm_read_byte(&pSTR[i]));
}
}
// all the prints
void AF_XPort::print(uint8_t b) { xportserial.print(b); }
void AF_XPort::print(const char *b) { xportserial.print(b); }
void AF_XPort::print(char b) { xportserial.print(b); }
void AF_XPort::print(unsigned int b) { xportserial.print(b); }
void AF_XPort::print(long b) { xportserial.print(b); }
void AF_XPort::print(long b, int base) { xportserial.print(b, base); }
void AF_XPort::println(void) { xportserial.println(); }
void AF_XPort::println(const char c[]) { xportserial.println(c); }
void AF_XPort::println(uint8_t b) { xportserial.println(b); }
void AF_XPort::println(int b) { xportserial.println(b); }
void AF_XPort::println(long b) { xportserial.println(b); }
void AF_XPort::println(unsigned long b) { xportserial.println(b); }
void AF_XPort::println(long n, int base) { xportserial.println(n, base); }
And here is my code to test (I am using the adafruit Ethernet XPort+ module)
Code: Select all
#include <SoftwareSerial.h>
#include <AF_XPort.h>
#include <VirtualWire.h>
#define HTTPPATH "/xPortPost.php?"
#define WEB_HOST "<wonttellyou>"
#define IPADDR "xx.xx.xx.xx"
#define PORT 80
#define XPORT_RXPIN 2
#define XPORT_TXPIN 3
#define XPORT_RESETPIN 4
#define XPORT_DTRPIN 0
#define XPORT_CTSPIN 6
#define XPORT_RTSPIN 0
#define RX_PIN 8
#define LED_PIN 13
#define PIN_BUZZER 10
//*** Channel 1
//Baudrate 57600, I/F Mode 4C, Flow 00
//Port 10001
//Connect Mode : D4
//Send '+++' in Modem Mode enabled
//Show IP addr after 'RING' enabled
//Auto increment source port disabled
//Remote IP Adr: --- none ---, Port 00000
//Disconn Mode : 00
//Flush Mode : 77
AF_XPort xPortSerial = AF_XPort(XPORT_RXPIN, XPORT_TXPIN, XPORT_RESETPIN, XPORT_DTRPIN, XPORT_RTSPIN, XPORT_CTSPIN);
char linebuffer[256];
uint8_t errno;
void setup(void) {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
Serial.begin(9600);
Serial.print("Setup...");
// set the data rate for the SoftwareSerial port
xPortSerial.begin(57600);
delay(1000);
Serial.println("done.");
}
void loop()
{
httpPost("TOTO");
delay(5000);
}
int httpPost(char* json)
{
uint8_t ret;
char *found=0;
ret = xPortSerial.reset();
switch (ret) {
case ERROR_TIMEDOUT:
{
Serial.println("Timed out on reset!");
return 0;
}
case ERROR_BADRESP:
{
Serial.println("Bad respons on reset!");
return 0;
}
case ERROR_NONE:
{
Serial.println("Reset OK!");
break;
}
default:
Serial.println("Unknown error");
return 0;
}
// time to connect...
ret = xPortSerial.connect(IPADDR, PORT);
switch (ret) {
case ERROR_TIMEDOUT:
{
Serial.println("Timed out on connect");
return 0;
}
case ERROR_BADRESP:
{
Serial.println("Failed to connect");
return 0;
}
case ERROR_NONE:
{
Serial.println("Connected...");
break;
}
default:
Serial.println("Unknown error");
return 0;
}
xPortSerial.print("GET ");
xPortSerial.print(HTTPPATH);
xPortSerial.print(json);
xPortSerial.println(" HTTP/1.1");
Serial.print("GET ");
Serial.print(HTTPPATH);
Serial.print(json);
Serial.println(" HTTP/1.1");
xPortSerial.print("Host: ");
xPortSerial.println(WEB_HOST);
Serial.print("Host: ");
Serial.println(WEB_HOST);
xPortSerial.println("");
Serial.println("");
while (1) {
// read one line from the xport at a time
ret = xPortSerial.readline_timeout(linebuffer, 255, 3000); // 3s timeout
// if we're using flow control, we can actually dump the line at the same time!
Serial.print(linebuffer);
if (strstr(linebuffer, "HTTP/1.1 200 OK") == linebuffer)
ret = 1;
if (((errno == ERROR_TIMEDOUT) && xPortSerial.disconnected()) ||
((XPORT_DTRPIN == 0) &&
(linebuffer[0] == 'D') && (linebuffer[1] == 0))) {
Serial.println("\nDisconnected...");
return ret;
}
}
}
void base64encode(char *s, char *r) {
char padstr[4];
char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint8_t i, c;
uint32_t n;
i = 0;
c = strlen(s) % 3;
if (c > 0) {
for (i=0; c < 3; c++) {
padstr[i++] = '=';
}
}
padstr[i]=0;
i = 0;
for (c=0; c < strlen(s); c+=3) {
// these three 8-bit (ASCII) characters become one 24-bit number
n = s[c];
n <<= 8;
n += s[c+1];
if (c+2 > strlen(s)) {
n &= 0xff00;
}
n <<= 8;
n += s[c+2];
if (c+1 > strlen(s)) {
n &= 0xffff00;
}
// this 24-bit number gets separated into four 6-bit numbers
// those four 6-bit numbers are used as indices into the base64 character list
r[i++] = base64chars[(n >> 18) & 63];
r[i++] = base64chars[(n >> 12) & 63];
r[i++] = base64chars[(n >> 6) & 63];
r[i++] = base64chars[n & 63];
}
i -= strlen(padstr);
for (c=0; c<strlen(padstr); c++) {
r[i++] = padstr[c];
}
r[i] = 0;
Serial.println(r);
}
Thanks!