Virtualwire receiving negativ values problem

hey there! im strugeling to send an encoder value from an arduino mini pro to an arduino nano. im ussing a cheap RF transmitter and receiver from sparkfun.

the trasmitter side seams to work when i print the encoder value i get positv and negativ values.

but on the receiverside i only get positiv values from 0-255

here is the trasmitter code:

#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).
*/

receiverside:

#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];

any idea how i cant manage on the receiver side to receive values like -200 +500 ? :slight_smile:
chears and thx
janosch :slight_smile:

On the receiver, look at how you have declared buf. Then, look at the assignment statement at the end. It should be pretty obvious why the sign gets lost.

hey paul i forgot to mention that i get an compiling error if i dont use an unsigned int :frowning:

cheers

i forgot to mention that i get an compiling error if i dont use an unsigned int

If you don’t use it where?

On the sender, the data to be sent is stored in an array whose type is int (the signed is implied by the lack of the unsigned keyword, and isn’t explicitly required). The signed int array is cast to an unsigned collection of bytes.

The same process should be used on the receiver to receive the data into an int array, so the negative values aren’t modified.

sounds like what i need :-) but im affraid i dont know how the code will than look like :-/ hellppppp :-)

cheers and thx janosch

The first part, changing the variable type on the receiver is pretty simple:

uint8_t buf[3];

becomes

int buf[3];

The second part, lying to the function so that it thinks the array is the proper type is easy:

    vw_get_message((uint8_t)buf, &buflen);

You are telling the vw_get_message function to get some bytes off the wire, and store them in consecutive bytes in memory, starting at the memory addressed pointed to by buf. The function expects that the memory will have been allocated in uint8_t sized units, but the data that was written there was not in those size units. So, the actual array where the data is stored should be defined in the same units as the data was written onto the wire. The explicit cast tells the compiler that you know the array that the function expects to write to is a different size, and that you are OK with that.

great paul! thx for the explanation will try this later and tell you if it works :-)

cheers!