Pages: [1]   Go Down
Author Topic: Problemi con gestione dati via seriale tra 2 mega  (Read 722 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buongiorno a tutti, ho un problema che non riesco a risolvere nella comunicazione seriale tra 2 mega...
Innanzitutto la connessione funziona, ricevo stringhe e riesco anche a utilizzarle per accendere e spengere un relè collegato ad arduino (con circuitino a transistor), in pratica l'arduino che trasmette ha un ricevitore ir e gestisce gia correttamente dei rele collegati, tutte le stringhe che arrivano via "ir" vengono ritrasmesse via seriale. Il secondo arduino le riceve correttamente ma il relè cambia stato una volta su 20.. facendo un println dello stato della porta che comanda il relè coincide con il problema che ho, quindi non è un problema HW.
Ergo dovrebbe essere un problema SW, ma il codice è così striminzito che non capisco cosa possa essere, ho provato a "giocare" un po con il delay ma senza risolvere il problema.
Qualche idea? Grazie a tutti
Code:
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
int serialTVS = 0;
void setup(){
  Serial.begin(9600);
pinMode(31,OUTPUT);
}
//Loop ------------------------------------------------------------------
void loop(){
  //ricezione seriale
    if (stringComplete) {
    Serial.println(inputString);
    momstring= inputString;
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
if ((inputString == "A16E0CF3") || (serialTVS == 1)){
  if (digitalRead(31) == LOW)
 digitalWrite(31,HIGH);
else
  digitalWrite(31, LOW);
 serialTVS=0;
}
 delay(10);
  }
 
  //ricezione seriale
  void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Credo che quel 1 su 20 sia un evento mistico...ho riscritto da capo tutto e ora non fa più nulla (meglio così) a questo punto il problema credo sia l'if (inputString == "A16E0CF3") , a quanto ho capito bisognerebbe usare ' al posto di " ma ovviamente mi da errore di conversione da int a const char...
 smiley-sad-blue
Logged

Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 954
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

no in teoria dovrebbe andare bene con il doppio apice "
http://arduino.cc/en/Reference/StringComparison

nel tuo codice non vedo dichiarata la variabile momstring, prova a mettere l'ultimo codice che hai fatto che vediamo cosa può essere
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21244
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Non capisco perché usi delle stringhe. I valori del telecomando IR sono numeri e visualizzati per la comoditá in forma esadecimale.

Oltre al sketch di ricezione completo dovresti anche darci il sketch di spedizione completo. Temo che mandi 4 byte e li traduci in una stringa a 4 caratteri ma il controllo lo fai poi con una stringa i 8 caratteri.

Ciao Uwe


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie per le risposte, il momstring era una prova per "esportare" la stringa prima di essere cancellata dalla successiva scrittura dell'inputString da parte della comunicazione seriale.
Uwe come al solito dici bene, di norma il valore in uscita dalla libreria ir è esadecimale (il codice che verifico ma con "0x" davanti) il motivo per cui non verificavo il codice completo è che il print dell' l'imputstring mi dà come risultato la parte di codice che ho scritto, possibile che lo 0x davanti non venga scritto?
ho riprovato il codice di trasmissione seriale con un uno e un mega che ho in più e funziona... se mi si libera il salotto provo comunque ad aggiungere lo 0x davanti, per quanto riguarda la trasmissione ho banalmente utilizzato la libreria ir che ho trovato sul sito di arduino ed è lei che fa i print, io mi sono semplicemente limitato ad eliminare i print fissi (received by nec piuttosto che sony, ecc)
posto lo sketch di esempio (per vedere come esegue i print) io nella parte codice non ho cambiato quasi nulla come dicevo prima
Code:
/*
 * IRrecord: record and play back IR signals as a minimal
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * An IR LED must be connected to the output PWM pin 3.
 * A button must be connected to the input BUTTON_PIN; this is the
 * send button.
 * A visible LED can be connected to STATUS_PIN to provide status.
 *
 * The logic is:
 * If the button is pressed, send the IR code.
 * If an IR code is received, record it.
 *
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;
int BUTTON_PIN = 12;
int STATUS_PIN = 13;

IRrecv irrecv(RECV_PIN);
IRsend irsend;

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(BUTTON_PIN, INPUT);
  pinMode(STATUS_PIN, OUTPUT);
}

// Storage for the recorded code
int codeType = -1; // The type of code
unsigned long codeValue; // The code value if not raw
unsigned int rawCodes[RAWBUF]; // The durations if raw
int codeLen; // The length of the code
int toggle = 0; // The RC5/6 toggle state

// Stores the code for later playback
// Most of this code is just logging
void storeCode(decode_results *results) {
  codeType = results->decode_type;
  int count = results->rawlen;
  if (codeType == UNKNOWN) {
    Serial.println("Received unknown code, saving as raw");
    codeLen = results->rawlen - 1;
    // To store raw codes:
    // Drop first value (gap)
    // Convert from ticks to microseconds
    // Tweak marks shorter, and spaces longer to cancel out IR receiver distortion
    for (int i = 1; i <= codeLen; i++) {
      if (i % 2) {
        // Mark
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK - MARK_EXCESS;
        Serial.print(" m");
      }
      else {
        // Space
        rawCodes[i - 1] = results->rawbuf[i]*USECPERTICK + MARK_EXCESS;
        Serial.print(" s");
      }
      Serial.print(rawCodes[i - 1], DEC);
    }
    Serial.println("");
  }
  else {
    if (codeType == NEC) {
      Serial.print("Received NEC: ");
      if (results->value == REPEAT) {
        // Don't record a NEC repeat value as that's useless.
        Serial.println("repeat; ignoring.");
        return;
      }
    }
    else if (codeType == SONY) {
      Serial.print("Received SONY: ");
    }
    else if (codeType == RC5) {
      Serial.print("Received RC5: ");
    }
    else if (codeType == RC6) {
      Serial.print("Received RC6: ");
    }
    else {
      Serial.print("Unexpected codeType ");
      Serial.print(codeType, DEC);
      Serial.println("");
    }
    Serial.println(results->value, HEX);
    codeValue = results->value;
    codeLen = results->bits;
  }
}

void sendCode(int repeat) {
  if (codeType == NEC) {
    if (repeat) {
      irsend.sendNEC(REPEAT, codeLen);
      Serial.println("Sent NEC repeat");
    }
    else {
      irsend.sendNEC(codeValue, codeLen);
      Serial.print("Sent NEC ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == SONY) {
    irsend.sendSony(codeValue, codeLen);
    Serial.print("Sent Sony ");
    Serial.println(codeValue, HEX);
  }
  else if (codeType == RC5 || codeType == RC6) {
    if (!repeat) {
      // Flip the toggle bit for a new button press
      toggle = 1 - toggle;
    }
    // Put the toggle bit into the code to send
    codeValue = codeValue & ~(1 << (codeLen - 1));
    codeValue = codeValue | (toggle << (codeLen - 1));
    if (codeType == RC5) {
      Serial.print("Sent RC5 ");
      Serial.println(codeValue, HEX);
      irsend.sendRC5(codeValue, codeLen);
    }
    else {
      irsend.sendRC6(codeValue, codeLen);
      Serial.print("Sent RC6 ");
      Serial.println(codeValue, HEX);
    }
  }
  else if (codeType == UNKNOWN /* i.e. raw */) {
    // Assume 38 KHz
    irsend.sendRaw(rawCodes, codeLen, 38);
    Serial.println("Sent raw");
  }
}

int lastButtonState;

void loop() {
  // If button pressed, send the code.
  int buttonState = digitalRead(BUTTON_PIN);
  if (lastButtonState == HIGH && buttonState == LOW) {
    Serial.println("Released");
    irrecv.enableIRIn(); // Re-enable receiver
  }

  if (buttonState) {
    Serial.println("Pressed, sending");
    digitalWrite(STATUS_PIN, HIGH);
    sendCode(lastButtonState == buttonState);
    digitalWrite(STATUS_PIN, LOW);
    delay(50); // Wait a bit between retransmissions
  }
  else if (irrecv.decode(&results)) {
    digitalWrite(STATUS_PIN, HIGH);
    storeCode(&results);
    irrecv.resume(); // resume receiver
    digitalWrite(STATUS_PIN, LOW);
  }
  lastButtonState = buttonState;
}

 
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 251
Posts: 21244
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il 0x non lo scrive perché é solo per dire al compiler che il numero che segue é in esadecimale.
Mi serviva il codice con cui mandi i dati al secondo Arduino per capire cosa sta spedendo e se lo sketch che lo riceve lo vede bene.
Per favore dacci entrambi i sketch.
Ciao Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Eccoci, alla fine ho rimodificato il codice. Effettivamente mi continua a funzionare una volta su 15 (a differenza dei led che ho attaccato sulla porta 6 del mega)...mi viene da pensare che possa essere un problema dell'digitalRead...
vi posto il codice corretto a titolo informativo, alla fine la parte della trasmissione funziona regolarmente e la stringa che controllo in ricezione è corretta, magari può essere utile a chi controlla via seriale con la libreria irremote, grazie a tutti!

Code:
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

//Prese TV
int serialTVS = 0;
//lucetv
int serialLTV;
int scattoLuce = 50;
int Luce = 0;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);  
  pinMode(31,OUTPUT);
  pinMode(6, OUTPUT);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {    
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }  
  
//LuceTV
if((inputString == "A16EA45B") || (serialLTV == 1)){
    Luce = 150;
    }
    if(inputString == "A16E04FB"){
 Luce = Luce - scattoLuce;
  }    
    analogWrite(6,Luce);
//Presa tv
if ((inputString == "A16E0CF3") || (serialTVS == 1)){
  if (digitalRead(31) == LOW)
 digitalWrite(31,HIGH);
else
  digitalWrite(31, LOW);
 serialTVS=0;
}
}

void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}
« Last Edit: December 16, 2012, 01:21:53 pm by UweFederer » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Confermo un problema di lettura (digitalread) della porta, risolto creando una variabile boolean per lo stato di attivazione o meno dell'uscita, ora apre e chiude regolarmente.
Yuppy!  smiley-grin
Logged

Pages: [1]   Go Up
Jump to: