Smooth PWM changes from values over RF

Hi all,

I have made a wireless dimmer for a strip of LEDs. Everything works fairly well, but the dimming on the LED side is a bit jumpy as I'm sending the pot values over with a slight delay. I have an idea of how I can fix this on the receiver side, but I need some help structuring the code.

Essentially, I want to detect the direction of the change of the potentiometer value, then increment by one until the LEDs have reached the last value sent. Do you guys think this would work? I wonder if it will be too sensitive to quick up and down changes..? The actual implementation is a bit beyond me. Even a shove in the general direction would be helpful.

I hope this is understandable

Receiver Code:

#include <VirtualWire.h>
int ledPin = 3;
int Sensor1Data;
char Sensor1CharMsg[4]; 

void setup() {
  Serial.begin(9600);
  Serial.println("ready");
  pinMode(11, INPUT);  
  // sets the digital pin as output
  pinMode(ledPin, OUTPUT);      

    vw_setup(2000);     
    vw_rx_start();       

}

void loop(){
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
    // Non-blocking
    if (vw_get_message(buf, &buflen)) 
    {
    int i;
        for (i = 0; i < buflen; i++)
    {            
          Sensor1CharMsg[i] = char(buf[i]);
    }
        Sensor1CharMsg[buflen] = '\0';
        Sensor1Data = atoi(Sensor1CharMsg);
 
        Serial.print("Sensor 1: ");
        Serial.println(Sensor1Data);
        
        if (Sensor1Data <= 0){
        Sensor1Data = 0;
          }    
      
        analogWrite(ledPin, Sensor1Data);
        Serial.print("Sensor 1: ");
        Serial.println(Sensor1Data);
    }
}

Transmitter Code (only the essential parts I hope):

if (index >= numReadings)              
    index = 0;                
    average = total / numReadings;           
    sensorValue = map(average, 143, 1024, 1, 255);
    buttonState = digitalRead(buttonPin);

  switch (buttonState) {
    case 1:
      if (sensorValue > sensorValueOld || sensorValue < sensorValueOld){
        if (sensorValue <= 0){
          sensorValue = 1;
          }
        else if(sensorValue > 255){
          sensorValue = 255;
          }
        analogWrite(led, sensorValue);
        Serial.println(sensorValue);
        itoa(sensorValue,Sensor1CharMsg,10);
    
        vw_send((uint8_t *)Sensor1CharMsg, strlen(Sensor1CharMsg));
        vw_wait_tx(); // Wait until the whole message is gone
        
        sensorValueOld = sensorValue;
        break;
       }
       else {
         break;
       }

On the sender, you are mapping a value in the range 0 to 1023 using a from range of 143 to 1024 and a to range of 1 to 255. That means that the output will never be higher than 254, but could be less than 0.

Then, you test for values less than 0 and greater than 255, and reset them. The constrain() function would do that in one call, and shorten your code.

The end result, though, is that the value you send is never negative. There is no reason, then, on the receiver to test for negative numbers.

There is also no reason to copy the data from a uint8_t array to a char array. Just tell atoi() to treat the input as characters.

        Sensor1Data = atoi((const char *)buf);

What you would want to do is keep track of the previously received value, and compare that to the just received value, and if different, create a for loop, starting at the previous value, ending at the current value, incrementing or decrementing as appropriate, and analogWrite() the loop iteration value.