0

The general idea

I would like to target a link with certain parameters, which would trigger a force download of a txt file, to an SD card. Next, I'd like to loop through that file, and read one line at a time, doing something with each of the lines (storing in a variable, using it to send an SMS, etc). I'm using Arduino Uno + Ethernet shield.

Serverside script (PHP)

The serverscript does a DB query, and packs the results (first row/line in txt file - message text consisting of max 159 characters, all the other rows/lines - preformatted phone numbers, consisting of max 16 characters each) into a txt file. Newline and carriage returns for both the message and the phone numbers are added at the very end of, via

fwrite($txtFile,'+'.$cleanNum."\""."\r\n");

The plus sign and the escaped quote are there, because I'd like to have the numbers formatted like this

+389012345678"

because that prepares it for sending later on.

The Code

/*
 Circuit:
 Ethernet shield attached to pins 10, 11, 12, 13
 */

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <SD.h>

byte mac[] = {
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
String msg ="";
String allTxt = "";
int counter = 0;
int testRead = 0;
int testmsg = 1;

char server[] = "myserver.dev";

IPAddress ip(192, 168, 1, 200);
EthernetClient client;

File file;

void setup() {
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);

  Serial.begin(9600);
  while (!Serial) {}

  if (!SD.begin(4)) {
    return;
  }

  if (Ethernet.begin(mac) == 0) {
      Ethernet.begin(mac, ip);
  }
  delay(1000);

  if (client.connect(server, 80)) {
    client.println("GET /dl.php?param=pass HTTP/1.1");
    client.println("Host: myserver.dev");
    client.println("Connection: close");
    client.println();
  }

  if(SD.exists("numbers.txt"))
    SD.remove("numbers.txt");

  file = SD.open("numbers.txt", FILE_WRITE);

  if (!file)
    while (1);
}

String readLine() {
  String received = "";
  char ch;
  while(file.available()){
    ch = file.read();
    if(ch == '\n') {
      return String(received);
    } else {
      received+=ch;
    }
  }
  return "";
}

void loop() {
  if (client.available()) {
    char c = client.read();
    allTxt += c;
    if(c == (char)13) {
      counter++;
      if(counter > 13) {
        for(int i = 0; i < allTxt.length()-1; i++) {
          file.print(allTxt[i]);
        }
      }
      allTxt = "";
    }
  }

  if (!client.connected()) {
    client.stop();
    file.close();
    if(testRead < 1) {
      testRead++;
      file = SD.open("numbers.txt", FILE_READ);
      if(file) {
        Serial.println("File opened!");
        while(file.available()) {
          if(testmsg==1){
            msg += readLine();
            Serial.println(msg);
            testmsg++;
          } else {
            Serial.println(readLine());
          }
        }
      }
      file.close();
    }
    Serial.println("**********************************");
    Serial.println("end");
    while(true);
  }
}

The Problem

Whenever the first row in the downloaded txt file has more than 110 characters, the code does not read it (although it IS present in the file). Since it's not being read, it's not being stored in the String msg variable.

Things tried

Breaking the message into two variables (on the server, inside the PHP script), via

$msgOne = substr($msg,0,floor(strlen($msg)/2)-1);
$msgTwo = substr($msg,floor(strlen($msg)/2)-1);

and then writing them as individual rows / lines of text into the txt file. The Arduino code is modified to include this change, with

msg += readLine();
msg += readLine();

This however, fills the msg variable with just the first part of the message.

Redeclaring msg as a chararray, and replacing msg+=readLine() with

readLine().toCharArray(msg,159);

also gave no results.

I have also tried replacing readLine() with Serial.println(file.read()), and everything is printed to Serial, so I'm guessing that something's wrong with my readLine() function. Maybe it (or Arduino itself) can't handle 159 characters in the first row.

Any help is appreciated.

1
  • Add code to check when String fails :) Dec 13, 2016 at 13:56

1 Answer 1

0

The problem was in a newline character (I still haven't discovered where does it come from or why). I have resolved it by changing this part

    while(file.available()) {
      if(testmsg==1){
        msg += readLine();
        Serial.println(msg);
        testmsg++;
      } else {
        Serial.println(readLine());
      }
    }

into this

    while(file.available()) {
       while(testRead<3) {
        char c = file.read();
        if(c != '\n') {
          msg += c;
        } else {
          testRead++;
        }
      }
      Serial.println(readLine());
      }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.