sleemanj / optiboot

Small and Fast Bootloader for Arduino and other Atmel AVR chips
66 stars 13 forks source link

Code issue: maybe a bug with map function? #17

Closed skaman82 closed 5 years ago

skaman82 commented 5 years ago

Hi, first of all great work! This is really awsome to work with. I am currently working on some code for the ATtiny85 and the strange thing is, that it is working just fine on the Arduino nano but not on the ATtiny85 using your hardware core. I am reading a PWM value from an RC receiver and using it to change colors on a LED strip.

`#include

define WSLED_PIN 4 // 3 nano | 4 at85

define PWM_PIN 2 // 2 all

define NUMPIXELS 16

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, WSLED_PIN, NEO_GRB + NEO_KHZ800);

int pwm_value;

void setup() { pinMode(PWM_PIN, INPUT); pixels.begin(); // This initializes the NeoPixel library. pixels.clear(); }

void loop() {

pwm_value = pulseIn(PWM_PIN, HIGH); byte color = map(pwm_value, 2000, 1000, 0, 255);

for (int i = 0; i < 16; i++) { pixels.setPixelColor(i, Wheel(color)); }

pixels.show(); delay(10);

}

// Input a value 0 to 255 to get a color value. // The colours are a transition r - g - b - back to r. uint32_t Wheel(byte WheelPos) { WheelPos = 255 - WheelPos; if (WheelPos < 85) { return pixels.Color(255 - WheelPos 3, 0, WheelPos 3); } if (WheelPos < 170) { WheelPos -= 85; return pixels.Color(0, WheelPos 3, 255 - WheelPos 3); } WheelPos -= 170; return pixels.Color(WheelPos 3, 255 - WheelPos 3, 0);

}`

I am getting the "pwm_value" but as soon I use the "map" function to map it from 1000-2000 to 0-255. It is not working anymore. Same Code is working just fine on the Arduino Nano. Is this a bug or I am doing something wrong?

sleemanj commented 5 years ago

With an input value of 1500, the map code in my core produces 127 as the answer, which is the same as the normal arduino answer.

I suggest you setup a test case with serial outout without the neopixel code to see what you are getting, ie..

  #define PWM_PIN 2 
  int pwm_value;

  void setup() {
    pinMode(PWM_PIN, INPUT);
    Serial.begin(9600);
  }

  void loop() {

    pwm_value = pulseIn(PWM_PIN, HIGH); 
    byte color = map(pwm_value, 2000, 1000, 0, 255);

    Serial.print(" In: ");  Serial.println(pwm_value);
    Serial.print(" Map: ");  Serial.println(color);

    delay(10);

  }

it may be a problem in neopixel instead of map as you assert (I seem to recall neopixel does some funny stuff under the hood, but I haven't used it personally), you could also change the code to use neopixel without mapping (ie, hard-code some values for testing) to test that.

skaman82 commented 5 years ago

@sleemanj Thank you for your quick reply. Yes it might be the neopixel library. I found a workaround in the meantime that is working good enough:

pwm_value = pulseIn(PWM_PIN, HIGH);

uint16_t color_calc = pwm_value - 2000; //should be 1000 in theory but this works, 1000 produces a double cycle in the colorwheel throughout the pwm range

  if (color_calc < 0) {
    color_calc = 0;
  }
  if (color_calc > 1000) {
    color_calc = 1000;
  }

  byte color_calc_result = color_calc >> 2; //bitshift 10 to 8 bits to get 0-250

for (int i = 0; i < 16; i++) {
    pixels.setPixelColor(i, Wheel(color_calc_result));
  }
  pixels.show();
  delay(10);