hallo
meine wetterstation sammelt laufend Daten die auf einer SDkarte gespeichert werden.
Nun möchte ich die Datei periodisch via FTP auf meinen Rechner pushen.
Auslösen will ich das nicht mit einem Taster sondern mit einer IR-Fernbedienung.
Ich habe nun einen Versuchsaufbau gemacht, der aus einem Duemillanove, einem Ethernet shield und dem IR-Empfänger (Typ 1883) besteht.
Dazu hab ich zwei Programme, den FTP-Client und die IR-Steuerung separat ausgetestet und die tun was sie sollen ...
FTP: bei Eingabe von "f" wird die Datei "test.txt" von der SDkarte auf den FTPserver geschickt. (mit "r" wird sie auf dem Serial Monitor gedumpt)
Code:
/*
FTP passive client for IDE v1.0.1 and w5100/w5200
Posted October 2012 by SurferTim
*/
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
// comment out next line to write to SD from FTP server
#define FTPWRITE;
// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x77 };
// change to your network settings
IPAddress ip( 192, 168, 1, 177 );
// IPAddress gateway( 192, 168, 2, 1 );
// IPAddress subnet( 255, 255, 255, 0 );
// change to your server
IPAddress server( 192, 168, 1, 109 ); // guck mit ipconfig /all was der PC für eine IP hat
EthernetClient client;
EthernetClient dclient;
char outBuf[128];
char outCount;
// change fileName to your file (8.3 format!)
char fileName[13] = "test.txt";
File fh;
void setup()
{
Serial.begin(57600);
pinMode(10,OUTPUT);
digitalWrite(10,HIGH);
if(SD.begin(4) == 0)
{
Serial.println(F("SD init fail"));
}
// Ethernet.begin(mac, ip, gateway, gateway, subnet);
Ethernet.begin(mac, ip);
digitalWrite(10,HIGH);
delay(2000);
Serial.println(F("Ready. Press f or r"));
}
void loop()
{
byte inChar;
inChar = Serial.read();
if(inChar == 'f')
{
if(doFTP()) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
}
if(inChar == 'r')
{
readSD();
}
}
byte doFTP()
{
#ifdef FTPWRITE
fh = SD.open(fileName,FILE_READ);
#else
SD.remove(fileName);
fh = SD.open(fileName,FILE_WRITE);
#endif
if(!fh)
{
Serial.println(F("SD open fail"));
return 0;
}
#ifndef FTPWRITE
if(!fh.seek(0))
{
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
#endif
Serial.println(F("SD opened"));
if (client.connect(server,21)) {
Serial.println(F("Command connected"));
}
else {
fh.close();
Serial.println(F("Command connection failed"));
return 0;
}
if(!eRcv()) return 0;
client.println(F("USER myuser"));
if(!eRcv()) return 0;
client.println(F("PASS mypassword"));
if(!eRcv()) return 0;
client.println(F("SYST"));
if(!eRcv()) return 0;
client.println(F("PASV"));
if(!eRcv()) return 0;
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL)
{
Serial.println(F("Bad PASV Answer"));
}
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(server,hiPort)) {
Serial.println(F("Data connected"));
}
else {
Serial.println(F("Data connection failed"));
client.stop();
fh.close();
return 0;
}
#ifdef FTPWRITE
client.print(F("STOR "));
client.println(fileName);
#else
client.print(F("RETR "));
client.println(fileName);
#endif
if(!eRcv())
{
dclient.stop();
return 0;
}
#ifdef FTPWRITE
Serial.println(F("Writing"));
byte clientBuf[64];
int clientCount = 0;
while(fh.available())
{
clientBuf[clientCount] = fh.read();
clientCount++;
if(clientCount > 63)
{
dclient.write(clientBuf,64);
clientCount = 0;
}
}
if(clientCount > 0) dclient.write(clientBuf,clientCount);
#else
while(dclient.connected())
{
while(dclient.available())
{
char c = dclient.read();
fh.write(c);
Serial.write(c);
}
Serial.println("----------------------------------------------------")
Serial.println();
}
#endif
dclient.stop();
Serial.println(F("Data disconnected"));
if(!eRcv()) return 0;
client.println(F("QUIT"));
if(!eRcv()) return 0;
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
while(!client.available()) delay(1);
respCode = client.peek();
outCount = 0;
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
if(outCount < 127)
{
outBuf[outCount] = thisByte;
outCount++;
outBuf[outCount] = 0;
}
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
client.println(F("QUIT"));
while(!client.available()) delay(1);
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
}
void readSD()
{
fh = SD.open(fileName,FILE_READ);
if(!fh)
{
Serial.println(F("SD open fail"));
return;
}
while(fh.available())
{
Serial.write(fh.read());
}
fh.close();
Serial.println();
Serial.println("------------------- file read finished ---------------------------------");
Serial.println();
}
Nun die auf meine IR-Steuerung angepassten codes. Es wird einfach die gedrückte Taste im Seriel Monitor ausgegeben.
Code:
/* CHANGED 20141225
for IR Car-mp3 remote control
shows only pressed button
RGB Remote Control
by: Jim Lindblom
SparkFun Electronics
date: October 1, 2013
This sketch uses Ken Shirriff's *awesome* IRremote library:
https://github.com/shirriff/Arduino-IRremote
RGB Remote Control uses a combination of SparkFun's
IR Remote (https://www.sparkfun.com/products/11759) and an
IR receiver diode (https://www.sparkfun.com/products/10266) to
control an RGB LED.
The IR Remote's power button turns the LED on or off. The A, B,
and C buttons select a channel (red, green, or blue). The up
and down arrows increment or decrement the LED brightness on that channel.
The left and right arrows turn a channel to min or max, and
circle set it to the middle.
Hardware setup:
* The output of an IR Receiver Diode (38 kHz demodulating
version) should be connected to the Arduino's pin 11.
* The IR Receiver diode should also be powered off the
Arduino's 5V and GND rails.
* A common cathode RGB LED is connected to Arduino's pins
5, 9, and 6 (red, green, and blue pins).
*/
#include <IRremote.h> // Include the IRremote library
/* Setup constants for Car-mp3 IR Remote: */
#define NUM_BUTTONS 21 // The remote has 3x7 buttons
/* Define the IR remote button codes. We're only using the
least signinficant two bytes of these codes. Each one
should actually have 0xFF in front of it. Find these codes
by running the IRrecvDump example sketch included with
the IRremote library.*/
const uint16_t BUTTON_11 = 0xFFA25D ;
const uint16_t BUTTON_12 = 0xFF629D ;
const uint16_t BUTTON_13 = 0xFFE21D ;
const uint16_t BUTTON_21 = 0xFF22DD ;
const uint16_t BUTTON_22 = 0xFF02FD ;
const uint16_t BUTTON_23 = 0xFFC23D ;
const uint16_t BUTTON_31 = 0xFFE01F ;
const uint16_t BUTTON_32 = 0xFFA857 ;
const uint16_t BUTTON_33 = 0xFF906F ;
const uint16_t BUTTON_41 = 0xFF6897 ;
const uint16_t BUTTON_42 = 0xFF9867 ;
const uint16_t BUTTON_43 = 0xFFB04F ;
const uint16_t BUTTON_51 = 0xFF30CF ;
const uint16_t BUTTON_52 = 0xFF18E7 ;
const uint16_t BUTTON_53 = 0xFF7A85 ;
const uint16_t BUTTON_61 = 0xFF10EF ;
const uint16_t BUTTON_62 = 0xFF38C7 ;
const uint16_t BUTTON_63 = 0xFF5AA5 ;
const uint16_t BUTTON_71 = 0xFF42BD ;
const uint16_t BUTTON_72 = 0xFF4AB5 ;
const uint16_t BUTTON_73 = 0xFF52AD ;
const uint16_t BUTTON_00 = 0xFFFFFF ;
/* Connect the output of the IR receiver diode to pin 11. */
int RECV_PIN = 11;
/* Initialize the irrecv part of the IRremote library */
IRrecv irrecv(RECV_PIN);
decode_results results; // This will store our IR received codes
uint16_t lastCode = 0; // This keeps track of the last code RX'd
void setup()
{
Serial.begin(57600); // Use serial to debug.
irrecv.enableIRIn(); // Start the receiver
}
// loop() constantly checks for any received IR codes.
void loop()
{
if (irrecv.decode(&results))
{
/* read the RX'd IR into a 16-bit variable: */
uint16_t resultCode = (results.value & 0xFFFF);
/* The remote will continue to spit out 0xFFFFFFFF if a
button is held down. If we get 0xFFFFFFF, let's just
assume the previously pressed button is being held down */
// if (resultCode == 0xFFFF)
// resultCode = lastCode;
// else
// lastCode = resultCode;
// delay(100);
// This switch statement checks the received IR code against
// all of the known codes. Each button press produces a
// serial output.
switch (resultCode)
{
case BUTTON_11:
Serial.println("CH-");
break;
case BUTTON_12:
Serial.println("CH");
break;
case BUTTON_13:
Serial.println("CH+");
break;
case BUTTON_21:
Serial.println("<<");
break;
case BUTTON_22:
Serial.println(">>");
break;
case BUTTON_23:
Serial.println(">");
break;
case BUTTON_31:
Serial.println("-");
break;
case BUTTON_32:
Serial.println("+");
break;
case BUTTON_33:
Serial.println("EQ");
break;
case BUTTON_41:
Serial.println("0");
break;
case BUTTON_42:
Serial.println("100");
break;
case BUTTON_43:
Serial.println("200");
break;
case BUTTON_51:
Serial.println("1");
break;
case BUTTON_52:
Serial.println("2");
break;
case BUTTON_53:
Serial.println("3");
break;
case BUTTON_61:
Serial.println("4");
break;
case BUTTON_62:
Serial.println("5");
break;
case BUTTON_63:
Serial.println("6");
break;
case BUTTON_71:
Serial.println("7");
break;
case BUTTON_72:
Serial.println("8");
break;
case BUTTON_73:
Serial.println("9");
break;
case BUTTON_00:
Serial.println("...repeated ...");
break;
default:
Serial.print("Unrecognized code received: 0x");
Serial.println(results.value, HEX);
break;
}
irrecv.resume(); // Receive the next value
}
}
Wenn ich nun diese zwei Programme kombiniere passiert folgendes
// ----------------------------------------------------------------------------
// my findings:
// pin 2 : readSD ("r") works from serial input and with the IRremote ("5") BUT "f" or "+" FAILS <----- !!!
// pin 3 : as 2
// pin 4 could not be used; reserved for SDselect
// pin 5 : as 2
// pin 6 : as 2
// pin 7 : as 2
// pin 8 : as 2
// pin 9 : as 2
// pin 10 could not be used; reserved for SDselect
// pin 11 : original setup nothing works; neither keyboard nor IRremote (SD open fail) <------------------ !!!
// pin 12 : only 'r' works, but displays unrecognized code at the end
// ----------------------------------------------------------------------------
code snippet (ganzer code ist am Ende angehängt!!)
Code:
...
case BUTTON_32:
Serial.println("+");
Serial.println("Uebermittlung startet ...");
if(doFTP()) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
break;
...
von "+" geht's zur FTP routine, die als erstes die SD karte lesen möchte
fh = SD.open(fileName,FILE_READ);
aber genau dasselbe passiert in der read&display-routine ...
und dort funktionierts
hier noch der SerialMonitor für IR an PIN_11 resp an PIN_2 (alle Ergebnisse: siehe oben)
-----------------------------------------------------------------------------
PIN_11:
Ready. press 'f' or 'r' on keyboard or with IRremote use CH , + for transmit
CH
Bitte FTPserver starten und + druecken zum Start der Uebermittlung...
+
Uebermittlung startet ...
SD open fail
FTP FAIL
PIN_2:
Ready. press 'f' or 'r' on keyboard or with IRremote use CH , + for transmit
CH
Bitte FTPserver starten und + druecken zum Start der Uebermittlung...
+
Uebermittlung startet ...
SD open fail
FTP FAIL
nun die "5" auf der IR gedrückt
5
Lorem ipsum dolor sit amet, ...
nun dasselbe durch Eingabe von "f"
Ready. press 'f' or 'r' on keyboard or with IRremote use CH , + for transmit
SD open fail
FTP FAIL
und nun von "r"
Lorem ipsum dolor sit amet, conset
-----------------------------------------------------------------------------
leider bin ich nicht in der Lage die libraries zu analysieren (oder ist der Fehler im code?) und hoffe auf hilfe aus der community
vielen dank und en guete rutsch iis 2015 ...
urs
vollständiger code:
Code:
/*
FTP passive client for IDE v1.0.1 and w5100/w5200
Posted October 2012 by SurferTim
combined with IRreceiver-library from RGB Remote Control (sparkfun.com)
used hardware:
Arduino Duemillanove with 328
Ethernet shield (original!)
SDmicro 4GB, containing one file
IRreceiver: typ 1838
*/
#include <SD.h>
#include <SPI.h>
#include <Ethernet.h>
#include <IRremote.h> // Include the IRremote library
// comment out next line to write to SD from FTP server
#define FTPWRITE;
#define NUM_BUTTONS 21; // my remote has 3x7 buttons
const uint16_t BUTTON_11 = 0xFFA25D ;
const uint16_t BUTTON_12 = 0xFF629D ;
const uint16_t BUTTON_13 = 0xFFE21D ;
const uint16_t BUTTON_21 = 0xFF22DD ;
const uint16_t BUTTON_22 = 0xFF02FD ;
const uint16_t BUTTON_23 = 0xFFC23D ;
const uint16_t BUTTON_31 = 0xFFE01F ;
const uint16_t BUTTON_32 = 0xFFA857 ;
const uint16_t BUTTON_33 = 0xFF906F ;
const uint16_t BUTTON_41 = 0xFF6897 ;
const uint16_t BUTTON_42 = 0xFF9867 ;
const uint16_t BUTTON_43 = 0xFFB04F ;
const uint16_t BUTTON_51 = 0xFF30CF ;
const uint16_t BUTTON_52 = 0xFF18E7 ;
const uint16_t BUTTON_53 = 0xFF7A85 ;
const uint16_t BUTTON_61 = 0xFF10EF ;
const uint16_t BUTTON_62 = 0xFF38C7 ;
const uint16_t BUTTON_63 = 0xFF5AA5 ;
const uint16_t BUTTON_71 = 0xFF42BD ;
const uint16_t BUTTON_72 = 0xFF4AB5 ;
const uint16_t BUTTON_73 = 0xFF52AD ;
const uint16_t BUTTON_00 = 0xFFFFFF ;
// ----------------------------------------------------------------------------
// my findings:
// pin 2 : readSD works from serial input and with the IRremote
// pin 3 : as 2
// pin 4 could not be used; reserved for SDselect
// pin 5 : as 2
// pin 6 : as 2
// pin 7 : as 2
// pin 8 : as 2
// pin 9 : as 2
// pin 10 could not be used; reserved for SDselect
// pin 11 : original setup nothing works; neither keyboard nor IRremote (SD open fail)
// pin 12 : only 'r' works, but displays unrecognized code at the end
// ----------------------------------------------------------------------------
/* Connect the output of the IR receiver diode to pin 11. */
int RECV_PIN = 11;
/* Initialize the irrecv part of the IRremote library */
IRrecv irrecv(RECV_PIN);
decode_results results; // This will store our IR received codes
uint16_t lastCode = 0; // This keeps track of the last code RX'd
// this must be unique
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x59, 0x77 };
// change to your network settings
IPAddress ip( 192, 168, 1, 177 );
// IPAddress gateway( 192, 168, 2, 1 );
// IPAddress subnet( 255, 255, 255, 0 );
// change to your server W I C H T I G
IPAddress server( 192, 168, 1, 109 ); // guck mit ipconfig /all was der PC für eine IP hat
EthernetClient client;
EthernetClient dclient;
char outBuf[128];
char outCount;
// change fileName to your file (8.3 format!)
char fileName[13] = "test.txt";
File fh;
void setup()
{
Serial.begin(57600);
pinMode(10,OUTPUT);
digitalWrite(10,HIGH); // disable Ethernet part during SDinit
if(SD.begin(4) == 0)
{
Serial.println(F("SD init fail"));
}
Ethernet.begin(mac, ip);
digitalWrite(10,HIGH);
delay(2000);
Serial.println(F("Ready. press 'f' or 'r' on keyboard or with IRremote use CH , + for transmit"));
// disable next line and others below it works!
irrecv.enableIRIn(); // Start the IR-receiver
}
void loop()
{
byte inChar;
inChar = Serial.read();
if(inChar == 'f')
{
if(doFTP()) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
}
if(inChar == 'r')
{
readSD();
}
// disable if construct and one above; it works
if (irrecv.decode(&results))
{
/* read the RX'd IR into a 16-bit variable: */
uint16_t resultCode = (results.value & 0xFFFF);
/* The remote will continue to spit out 0xFFFFFFFF if a
button is held down. If we get 0xFFFFFFF, let's just
assume the previously pressed button is being held down */
// if (resultCode == 0xFFFF)
// resultCode = lastCode;
// else
// lastCode = resultCode;
delay(100);
// This switch statement checks the received IR code against
// all of the known codes. Each button press produces a
// serial output.
switch (resultCode)
{
case BUTTON_11:
Serial.println("CH-");
break;
case BUTTON_12:
Serial.println("CH");
Serial.println("Bitte FTPserver starten und + druecken zum Start der Uebermittlung...");
break;
case BUTTON_13:
Serial.println("CH+");
break;
case BUTTON_21:
Serial.println("<<");
break;
case BUTTON_22:
Serial.println(">>");
break;
case BUTTON_23:
Serial.println(">");
break;
case BUTTON_31:
Serial.println("-");
break;
case BUTTON_32:
Serial.println("+");
Serial.println("Uebermittlung startet ...");
if(doFTP()) Serial.println(F("FTP OK"));
else Serial.println(F("FTP FAIL"));
break;
case BUTTON_33:
Serial.println("EQ");
break;
case BUTTON_41:
Serial.println("0");
break;
case BUTTON_42:
Serial.println("100");
break;
case BUTTON_43:
Serial.println("200");
break;
case BUTTON_51:
Serial.println("1");
break;
case BUTTON_52:
Serial.println("2");
break;
case BUTTON_53:
Serial.println("3");
break;
case BUTTON_61:
Serial.println("4");
break;
case BUTTON_62:
Serial.println("5");
readSD();
break;
case BUTTON_63:
Serial.println("6");
break;
case BUTTON_71:
Serial.println("7");
break;
case BUTTON_72:
Serial.println("8");
break;
case BUTTON_73:
Serial.println("9");
break;
case BUTTON_00:
Serial.println("...repeated...");
break;
default:
Serial.print("Unrecognized code received: 0x");
Serial.println(results.value, HEX);
break;
}
irrecv.resume(); // Receive the next value
}
// disable up to here
}
byte doFTP()
{
#ifdef FTPWRITE
fh = SD.open(fileName,FILE_READ);
#else
SD.remove(fileName);
fh = SD.open(fileName,FILE_WRITE);
#endif
if(!fh)
{
Serial.println(F("SD open fail"));
return 0;
}
#ifndef FTPWRITE
if(!fh.seek(0))
{
Serial.println(F("Rewind fail"));
fh.close();
return 0;
}
#endif
Serial.println(F("SD opened"));
if (client.connect(server,21)) {
Serial.println(F("Command connected"));
}
else {
fh.close();
Serial.println(F("Command connection failed"));
return 0;
}
if(!eRcv()) return 0;
client.println(F("USER myuser"));
if(!eRcv()) return 0;
client.println(F("PASS mypassword"));
if(!eRcv()) return 0;
client.println(F("SYST"));
if(!eRcv()) return 0;
client.println(F("PASV"));
if(!eRcv()) return 0;
char *tStr = strtok(outBuf,"(,");
int array_pasv[6];
for ( int i = 0; i < 6; i++) {
tStr = strtok(NULL,"(,");
array_pasv[i] = atoi(tStr);
if(tStr == NULL)
{
Serial.println(F("Bad PASV Answer"));
}
}
unsigned int hiPort,loPort;
hiPort = array_pasv[4] << 8;
loPort = array_pasv[5] & 255;
Serial.print(F("Data port: "));
hiPort = hiPort | loPort;
Serial.println(hiPort);
if (dclient.connect(server,hiPort)) {
Serial.println(F("Data connected"));
}
else {
Serial.println(F("Data connection failed"));
client.stop();
fh.close();
return 0;
}
#ifdef FTPWRITE
client.print(F("STOR "));
client.println(fileName);
#else
client.print(F("RETR "));
client.println(fileName);
#endif
if(!eRcv())
{
dclient.stop();
return 0;
}
#ifdef FTPWRITE
Serial.println(F("Writing"));
byte clientBuf[64];
int clientCount = 0;
while(fh.available())
{
clientBuf[clientCount] = fh.read();
clientCount++;
if(clientCount > 63)
{
dclient.write(clientBuf,64);
clientCount = 0;
}
}
if(clientCount > 0) dclient.write(clientBuf,clientCount);
#else
while(dclient.connected())
{
while(dclient.available())
{
char c = dclient.read();
fh.write(c);
Serial.write(c);
}
}
#endif
dclient.stop();
Serial.println(F("Data disconnected"));
if(!eRcv()) return 0;
client.println(F("QUIT"));
if(!eRcv()) return 0;
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
while(!client.available()) delay(1);
respCode = client.peek();
outCount = 0;
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
if(outCount < 127)
{
outBuf[outCount] = thisByte;
outCount++;
outBuf[outCount] = 0;
}
}
if(respCode >= '4')
{
efail();
return 0;
}
return 1;
}
void efail()
{
byte thisByte = 0;
client.println(F("QUIT"));
while(!client.available()) delay(1);
while(client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
client.stop();
Serial.println(F("Command disconnected"));
fh.close();
Serial.println(F("SD closed"));
}
void readSD()
{
fh = SD.open(fileName,FILE_READ);
if(!fh)
{
Serial.println(F("SD open fail"));
return;
}
while(fh.available())
{
Serial.write(fh.read());
}
fh.close();
}
Lesezeichen