The new Raspberry Pi B Model B+ is here - Pick one up in the store and check our detailed guide!

Trying to build AF_XPort for Arduino 1.0.3

by strus_fr on Tue Feb 12, 2013 3:44 pm

Hi

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 | TOGGLE FULL SIZE
#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 | TOGGLE FULL SIZE
#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);
}


Any help would be very appreciated!
Thanks!
strus_fr
 
Posts: 3
Joined: Tue Apr 06, 2010 5:13 pm