Problema moduli TX RX

Salve con l'utilizzo dei moduli tx e rx volevo muovere un servo tramite un potenziometro; lo sketch non mi da errori ma praticamente non funziona... qualche anima pia mi aiuta a trovare qualche errore o mancanza?

Codice RX:

#include <SoftwareServo.h>
#include <VirtualWire.h>
SoftwareServo myservo;
void setup()
{
    Serial.begin(9600);
    Serial.println("setup");
    vw_set_rx_pin(5);
    vw_setup(2000);  // Bits per sec
 
    vw_rx_start();       // Start
    myservo.attach(9);
}
 
void loop()
{

    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
 
 if (vw_get_message(buf, &buflen)) 
    { int data;
    digitalWrite(13, true);
       data = (int(buf[2]<<8)+buf[1]);
       data = map(data, 0, 1023, 0, 179);
       myservo.write(data);                  // comando il servo con il valore letto 
    }
     delay(1000);
     SoftwareServo::refresh();
}

Codice TX:

#include <VirtualWire.h>
int data;

void setup()
{
  pinMode(13, OUTPUT);
  vw_set_tx_pin(2);
  vw_set_ptt_inverted(true); 
  vw_setup(2000);    // Bits per sec
}

void loop()
{
  unsigned int Data;
  byte TxBuffer[2];
    data = map(data, 0, 1023, 0, 179);
  data = analogRead(A0);

  TxBuffer[0] = data >> 8;
  TxBuffer[1] = data;
  digitalWrite(13, HIGH); 

  vw_send((byte *)TxBuffer, 2);
  digitalWrite(13, LOW); 
  delay(1000);
  }

nessuno? :frowning:

Che moduli hai usato? ... moduli "seri" o i solidi moduli "monnezza" cinesi da 1€ ?

In ogni caso la VirtualWire è obsoleta e non più manutenuta ...
... studiati la nuova RadioHead (... aggiornata e manutenuta) e prova ad usare quella ... ::slight_smile:

Guglielmo

Si i moduli sono cinesi, ma funzionano perfettamente. Avevo già provato con un programma semplice. Comunque grazie vedo cosa riesco a tirare fuori da Radiohead...e...dove posso trovare una lista con i comandi principali di questa libreria? mi faciliterebbe la vita :smiley:

Elfb:
... dove posso trovare una lista con i comandi principali di questa libreria? mi faciliterebbe la vita :smiley:

... nel link che ti ho dato trovi tutto quello che ti serve.

Guglielmo

Grazie, sono riusci a farli comunicare e a ricevere i valori con Radio Head, ho solo un piccolo dubbio a cui non riesco a venirne fuori:
ricevo valori da 0 a 1023 in char*
per farli leggere al servo devo trasformarli in int, come faccio la conversione?

Elfb:
... ricevo valori da 0 a 1023 in char*

mmm ... non è possibile, un campo "char" contiene valori che vanno da -128 a +127 ed in ogni caso è un 8 bit quindi NON può contenere un valore maggiore di 0xFF.

Sicuro che quello che vedi NON sia il valore del "pointer" (ovvero non un valore, ma l'indirizzo di memoria dove è depositato il valore) ... perché parli di char* che è appunto un puntatore !

Se è così puoi assegnare il valore puntato da char * ad una variabile di tipo char con la seguente assegnazione:

variabile_char = * variabile_puntatore_a_char;

Guglielmo

Non ho capito bene, sono confuso sul char e char* ti allego il programma ricevente:

#include <SoftwareServo.h>
#include <RH_ASK.h>
#include <SPI.h> // Non usata ma utilizzata per compilare correttamente
RH_ASK driver;
SoftwareServo myservo;

void setup()
{ 
  
  pinMode(13, OUTPUT);   
  Serial.begin(9600);  // Debugging 
  if (!driver.init())
    Serial.println("Inizializzazione modulo fallita!");
}

void loop() 
{   myservo.attach(9);
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);
    
    if (driver.recv(buf, &buflen)) 
        {
            buf[buflen] = '\0';
            int data;
            driver.printBuffer("Got:", buf, buflen);
            digitalWrite(13, HIGH);   // Comando valido ricevuto
            Serial.println((char*)buf); //vedo valori da 0 a 1023
            data = map(data, 0, 1023, 0, 170);
            Serial.println(data);  
            myservo.write(data);
        }
    digitalWrite(13, LOW);
    delay(100);               
  }

con Serial.println((char*)buf) vedo i valori che vanno da 0 a 1023 come faccio a dare quei valori alla variabile data (che è int)?

Ma tu cosa gli trasmetti ? Perché quello che hai scritto NON è molto chiaro ... buf è un array di byte NON segnati, cosa ci va a finire dentro ? Se non si sa cosa gli mandi come si fa a capire cosa estrarre ? Può contenere di tutto !

Guglielmo

Gli mando un valore analogico da un potenziometro (0 1023)

Quindi tu trasmetti 2 byte ovvero un int ? Uno ed uno solo ? Aggiungi caratteri particolari alla fine ?

Ma perché non metti pure la parte di trasmissione che almeno si vede che fai ?

Guglielmo

si eccola:

trasmissione:

#include <RH_ASK.h>
#include <SPI.h> // Non usata ma utilizzata per compilare correttamente
RH_ASK driver;

void setup() {
  pinMode(13, OUTPUT);     
  Serial.begin(9600);    // Debugging
  if (!driver.init())
    Serial.println("Inizializzazione modulo fallita!");
}

void loop() 
{
     digitalWrite(13, HIGH);
    int data = analogRead (A0); 
    Serial.println (data);
    char msg[4];
    itoa(data, msg, 10);
    driver.send((uint8_t *)msg, strlen(msg));
    driver.waitPacketSent();
    digitalWrite(13, LOW);
    delay(100);
}

... con quella itoa() tu stai trasformando un intero ("data") in una stringa di caratteri ASCII ... quindi

  1. msg[4] è troppo piccolo ... 1023 è già 4 caratteri, se mettiamo il terminatore di stringa (0x00) sei già fuori ... per essere sicuro dichiara quel msg di 6 caratteri e non ti sbagli.

  2. quella che ricevi è quindi una stringa di caratteri ASCII che va riconvertita in un int con la funzione atoi()

Guglielmo

Grazie Guglielmo, ho inserito la striga: data = atoi((char*)buf); ora vedo i valori correti inviati al servo però non si muove...devo far qualche altro passaggio? allego il codice

#include <SoftwareServo.h>
#include <RH_ASK.h>
#include <SPI.h> // Non usata ma utilizzata per compilare correttamente
RH_ASK driver;
SoftwareServo myservo;

void setup()
{ myservo.attach(3);
  pinMode(13, OUTPUT);   
  Serial.begin(9600);  // Debugging 
  if (!driver.init())
    Serial.println("Inizializzazione modulo fallita!");
}

void loop() 
{   
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);
    
    if (driver.recv(buf, &buflen)) // Non-blocking
        {
            buf[buflen] = '\0';
            int data;
            driver.printBuffer("Got:", buf, buflen);
            digitalWrite(13, HIGH);   // Comando su indirizzo valido ricevuto
            Serial.println((char*)buf); //vedo valori da 0 a 1023
            data = atoi((char*)buf);
            data = map(data, 800, 1023, 0, 170);
            Serial.println(data);
            myservo.write(data);
        }
    digitalWrite(13, LOW);
    delay(100);               
  }

Non conosco la SoftwareServo ... come mai non usi la libreria standard Servo ?

Guglielmo

perchè servo.h mi davo problemi di compatibilità possibile?

comunque ora funziona mancava: SoftwareServo::refresh();

Però ora quando ricomincia il ciclo il servo torna alla posizine 0...nella liberia standard c'è un modo perchè rimanga fermo all'ultima posizione data?