RF Module + Virtualwire problem

Moin zusammen :slight_smile:
Ich versuche jetzt schon seid einer weile meinen Encoderwert von einem Arduino Mini Pro zu einem Arduio Nano zu schicken und werde bald verückt :slight_smile:

Ich benutze einen rf receiver und transiver von watterot

und die virtualwire.h library

bei der Transmitterseite scheint alles zufunktionieren:

#include <VirtualWire.h>
#define encoder0PinA  2
#define encoder0PinB  14
signed int numbers[3];
volatile signed int encoder0Pos = 125;


void setup()
{
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor
  attachInterrupt(0, doEncoder, CHANGE); 
  vw_set_ptt_inverted(true);
  vw_setup(2000);
  Serial.begin (9600); 
 Serial.println("start"); 
}

void loop()
{
   
  numbers[0] = encoder0Pos;    
  vw_send( (uint8_t *)numbers, sizeof(numbers));
  vw_wait_tx();  // Wait for message to finish
  delay(50);

Serial.println(numbers[0], DEC);
   
}

void doEncoder() {
  /* If pinA and pinB are both high or both low, it is spinning
   * forward. If they're different, it's going backward.
   *
   * For more information on speeding up this process, see
   * [Reference/PortManipulation], specifically the PIND register.
   */
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
  //Serial.print("encoderpos:"); 
//  Serial.println (encoder0Pos, DEC);
}

/* See this expanded function to get a better understanding of the
 * meanings of the four possible (pinA, pinB) value pairs:
 */
void doEncoder_Expanded(){
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
                                             // encoder is turning
      encoder0Pos = encoder0Pos - 1;         // CCW
    } 
    else {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  { 
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
                                              // encoder is turning  
      encoder0Pos = encoder0Pos + 1;          // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }

  }
  //Serial.println (encoder0Pos, DEC);          // debug - remember to comment out
                                              // before final program run
  // you don't want serial slowing down your program if not needed
}

/*  to read the other two transitions - just use another attachInterrupt()
in the setup and duplicate the doEncoder function into say, 
doEncoderA and doEncoderB. 
You also need to move the other encoder wire over to pin 3 (interrupt 1). 
*/

Serial.println(numbers[0], DEC); liefert mir so wie ich das wollte positive und negative werte.

bei der receiverseite habe ich da weniger glück ich bekomme es dort nicht hin negative werte zu empfangen, bekomme immer nur von 0-255

hier der code:

#include <VirtualWire.h>

uint8_t buf[3];
uint8_t buflen;
signed int encoder= 0;
signed long istpos = 125;
signed long abweichung = 0;
signed long  sollpos = 0;



void setup()
{
  
  
  buflen = 3;
    Serial.begin(9600); 
    Serial.println("start");
    vw_setup(2000); 
    vw_rx_start(); 
    
}

void loop()
{
    vw_get_message(buf, &buflen);
   
   Serial.println(buf[0],DEC);
   encoder = buf[0];

ist nur ein auschnitt aus dem code...

ich will auf der receiver seite damit einen stepper drehen und brauche hierfür sowohl positive als auch negative werte das ist ja das schöne an einem encoder sonst hätte ich gleich einen poti nehmen können :wink:

wie gesagt nochmal zusammengefast:
Die Transmitter seite also das numbers[0] enthält den richtigen encoder wert also positive und negative werte.

und bei der receiverseite bekomme ich es nicht hin das er diesen wert richtig emfängt

hat jemand eine idee?

lg und danke janosch

Ich vermute mal es werden nur Bytes übertragen, und der Empfänger weiss nicht ob die jetzt mit Vorzeichen (also 7 Bit Zahl + 1 Bit vorzeichen = Dezimal -126 ... 127) oder ohne Vorzeichen (also 8 Bit Zahl = Dezimal 0...255) sind.

Lösungsvorschläge:

a) Typecasting beim Empfänger:

Serial.println((int8)buf[0],DEC);

// keine Ahnung ob das so geht, da fehlt mir noch das Arduino/C KnowHow

b) Beim Sender 126 hinzuaddieren, beim Empfänger wieder abziehen :slight_smile:

uff also an der Emfängerseite kommt nur 0-255 an hmmmmmmmm habe schon probiert die 0-255 zu mappen aber das ändert ja nichts dran das ich auch werte über 300 von dem encoder bekomme...

das muss doch gehen das der doofe emfänger einfach ne -200 und +500 emfängt oder :wink:

lg janosch

"byte" sind immer ohne Vorzeichen, also "0"-"255". Wenn Du "-127"-"128" haben willst, dann caste nach "char". :slight_smile:

hmmmm aber ich brauche doch mehr als 125 hmmm und wenn ich was anderes als byte mit der emfang funktion mache bekomme ich einen fehler vom compiler :frowning:

hast du evtl einen beispiel code für das "casten"

lg janosch

PS bin leider nicht so ein programmierfuchs...eher ein zusammenkopierer :wink:

byte buf[3];
buf[0] = 200;
Serial.println(buf[0]) // -> "200"
Serial.println((char)buf[0]) // -> "-56"

Aber nagle mich nicht darauf fest, ich hab grad keinen Arduino zum Testen da... :wink:

byte buf[3];
buf[0] = 200;
Serial.println(buf[0]) // -> "200"
Serial.println((char)buf[0]) // -> "-56"

Aber nagle mich nicht darauf fest, ich hab grad keinen Arduino zum Testen da... Wink

ohhhh das sieht doch schonmal gut aus :slight_smile: kann ich auch so casten das es höhere werte gibt? char geht ja ur bis +125 -125 oder?

man man man bin da leider nen anfänger :slight_smile:

lg und danke janosch

Wenn Du nur Bytes übertragen kannst musst Du etwas tricksen. Dann kannst Du den großen Wert "aufspalten", übertragen und dann wieder "zusammenlegen".

Im Falle eines "long" ungefähr so:

byte buf[4];
*(long*)buf = 123456789;
// 123456789 == 0x075BCD15
Serial.println(buf[3]); // -> 0x07 == 7
Serial.println(buf[2]); // -> 0x5B == 91
Serial.println(buf[1]); // -> 0xCD == 205
Serial.println(buf[0]); // -> 0x15 == 21
// Jetzt kannst Du buf uebertragen...
// Empfaengerseitig kannst Du die Bytes dann wieder zusammenfuegen:
long val = buf[3]<<24 | buf[2]<<16 | buf[1]<<8 | buf[0];
// val hat jetzt 123456789

So oder so ähnlich.

Wenn Du nur ein "int" brauchst, also maximal +-32767, dann gehts auch mit zwei Bytes statt vier...

HUIIIIIIII also das sieht toll aus! und +- 32767 würde reichen .

ich stehe nur noch ein wenig auf dem schlauch :slight_smile:

nehmen wir mal an das die zahl von meinem encoder -2300 wäre und der receiver soll diese dann in dein int val schreiben..

wie ginge das :slight_smile:

Auf Encoderseite machst Du:

byte buf[2];
int encoderZahl = -2300;
*(int*)buf = encoderZahl;
vw_send(buf, sizeof(buf));

Und auf Receiverseite machst Du dann:

byte buf[2];
vw_get_message(buf, sizeof(buf));
int encoderZahl = buf[1]<<8 | buf[0];

Und fertig. :slight_smile:

Naja, oder so ähnlich. ::slight_smile:

jipi werde ich heute abend testen...nur das halt die encoderzahl variable ist aber das ja wurst wah :smiley:

vielen dank für die hilfe!!

Was Du da im Endeffekt reinschreibst (und wo Du den Wert herbekommst) ist wurscht (solange der Wert +-32767 nicht überschreitet!).

Hab jetzt zu Anschauungszwecken eben mal "-2300" hingeschrieben, weil Du den Wert erwähnt hattest. :wink:

hm hab gerade mal deinen code probiert

byte buf[2];
int encoderZahl = -2300;
*(int*)buf = encoderZahl;
vw_send(buf, sizeof(buf));

und bekomme beim compilieren ein:

error: expected unqualified-id before

Und was steht da noch so...? Das müsste eigentlich an was Anderem liegen...

Habs das jetzt mal zu Hause ausprobiert, und funktioniert. :slight_smile:

void setup() {
  Serial.begin(19200);
  
  byte buf[2];
  int encoderZahl = -2300;

  Serial.print("A: ");
  Serial.println(encoderZahl);
  *(int*)buf = encoderZahl;

  Serial.println(buf[0], HEX);
  Serial.println(buf[1], HEX);

  encoderZahl = buf[1]<<8 | buf[0]; 
  
  Serial.print("B: ");
  Serial.println(encoderZahl);
}

void loop() {
}

Ergibt

A: -2300
4
F7
B: -2300

strange....die transmitter seite geht aber die receiver seite zickt :frowning:

hier nen auszug :

#include <VirtualWire.h>

byte buf[2];
int DIR = 3;          // PIN  3 = DIR
int STEP = 2;        // PIN  2 = STEP
int MS1 = 13;        // PIN 13 = MS
int MS2 = 9;         // PIN  9 = MS2
int SLEEP = 12;      // PIN 12 = SLP
signed long istpos = 0;
signed long abweichung = 0;
signed long  sollpos = 0;


void setup()
{
  pinMode(DIR, OUTPUT);   // set pin 3 to output
  pinMode(STEP, OUTPUT);  // set pin 2 to output
  pinMode(MS1, OUTPUT);   // set pin 13 to output
  pinMode(MS2, OUTPUT);   // set pin 9 to output
  pinMode(SLEEP, OUTPUT); // set pin 12 to output  
  
  
    Serial.begin(9600); 
    Serial.println("get ab");
    vw_setup(2000); 
    vw_rx_start(); 
    
}

void loop()
{
  
  vw_get_message(buf, sizeof(buf));
  int encoder = buf[1]<<8 | buf[0]; 

    Serial.println(encoder,DEC);

dit liefert:

In function 'void loop()':
error: invalid conversion from 'unsigned int' to 'uint8_t*

motz :slight_smile:

Gehts in der loop() noch weiter...?
Sagt er was von wegen in welcher Zeile er Probleme hat?

hab mal nen bild gemacht :slight_smile:

scheint hier zu hängen:
" vw_get_message(buf, sizeof(buf));"

Öhm, kann es sein dass das vw_get_message für die Array-Länge einen Zeiger auf ein uint8_t haben will...?

hm keine ahnung aber diese get message funktion ist sehr schwer zu überzeugen :wink:

irrgendeine idee?

lg

Probier mal was in der Art:

char buf[2];
byte buflen = 2;
vw_get_message(buf, &buflen);

oder zur Not

uint8_t buflen = 2;