Всем доброго дня. Есть задача построить тахометр на ленте WS2812B В зависимости от оборотов растет столбик + меняется цвет. Но столкнулся с проблемой. Как-то криво работает функция map(); По определению данная функция берет значение переменной (в указанном диапазоне ) и преобразовывает в другом диапазоне. Если значения входной переменной выходят за пределы диапазона, то выставляется крайнее значение в указанном выходном диапазоне. В коде я четко указываю крайние значения 1-255, ро почему-то при выходе за пределы диапазона получаю не 1, а отрицательные значения, что приводит к засвету ленты не верным цветом. В мониторе порта показан переход границы в 4500 оборотов, когда Зеленая составляющая должна быть равной 1, а она вылазит в отрицательные значения. Кто может подсказать в чем кроется ошибка? вот что получаю с порта ======================== RPM= 4426 RED= 124 GREEN= 6 BLUE= 0 RPM= 4437 RED= 124 GREEN= 6 BLUE= 0 RPM= 4433 RED= 125 GREEN= 5 BLUE= 0 RPM= 4456 RED= 125 GREEN= 4 BLUE= 0 RPM= 4455 RED= 126 GREEN= 4 BLUE= 0 RPM= 4477 RED= 126 GREEN= 4 BLUE= 0 RPM= 4493 RED= 127 GREEN= 3 BLUE= 0 RPM= 4507 RED= 127 GREEN= 2 BLUE= 0 RPM= 4524 RED= 128 GREEN= 1 BLUE= 0 RPM= 4542 RED= 129 GREEN= 0 BLUE= 0 RPM= 4536 RED= 129 GREEN= -1 BLUE= 0 RPM= 4555 RED= 129 GREEN= -1 BLUE= 0 RPM= 4561 RED= 130 GREEN= -2 BLUE= 0 RPM= 4573 RED= 130 GREEN= -2 BLUE= 0 RPM= 4589 RED= 131 GREEN= -3 BLUE= 0 RPM= 4604 RED= 131 GREEN= -4 BLUE= 0 RPM= 4619 RED= 132 GREEN= -4 BLUE= 0 RPM= 4626 RED= 133 GREEN= -5 BLUE= 0 RPM= 4623 RED= 133 GREEN= -6 BLUE= 0 RPM= 4626 RED= 133 GREEN= -5 BLUE= 0 RPM= 4641 RED= 133 GREEN= -6 BLUE= 0 RPM= 4647 RED= 133 GREEN= -6 BLUE= 0 ======================== вот скетч ===================================== /* LedStripGradient: Example Arduino sketch that shows * how to control an Addressable RGB LED Strip from Pololu. * * To use this, you will need to plug an Addressable RGB LED * strip from Pololu into pin 12. After uploading the sketch, * you should see a pattern on the LED strip that fades from * green to pink and also moves along the strip. */ #include <PololuLedStrip.h> // Create an ledStrip object and specify the pin it will use. PololuLedStrip<12> ledStrip; // Create a buffer for holding the colors (3 bytes per color). #define LED_COUNT 12 rgb_color colors[LED_COUNT]; //конец лед ленты volatile unsigned long lastflash; int ledtaho, ledtahomax, ledtahodelta, RED, GREEN, BLUE, leddelta; volatile int RPM; void setup() { attachInterrupt(0, sens, RISING); Serial.begin(9600); pinMode(2, INPUT_PULLUP); for (uint16_t i = 0; i < LED_COUNT; i++) { colors = rgb_color(0, 0, 0); ledStrip.write(colors, LED_COUNT); } } void loop() { RPM = constrain(RPM, 0, 7500); // ledtaho = abs(RPM/550); ledtaho = abs(constrain((RPM/550), 0, 12)); /* Serial.print("RPM "); Serial.println(RPM); Serial.print("ledtaho "); Serial.println(ledtaho);*/ Serial.print("RPM= "); Serial.print(RPM); Serial.print(" RED= "); Serial.print(RED); Serial.print(" GREEN= "); Serial.print(GREEN); Serial.print(" BLUE= "); Serial.println(BLUE); if ((micros()-lastflash)>1000000) //если сигнала нет больше секунды { RPM=0; //считаем что RPM 0 for (uint16_t x = 0; x > LED_COUNT; x--) { colors[x] = rgb_color(0, 0, 0); ledStrip.write(colors, LED_COUNT); delay (10); } } // ledtaho = abs(RPM/550); // RPM = constrain(RPM, 0, 7500); // ledtaho = constrain(ledtaho, 0, 12); if (ledtaho > ledtahomax) { ledtahomax = ledtaho; } RED = map(RPM, 1500, 7500, 1, 255); GREEN = map(RPM, 0, 4500, 255, 1); BLUE = 0; for (uint16_t i = 1; i < ledtaho; i++) { colors = rgb_color(RED, GREEN, BLUE); ledStrip.write(colors, ledtaho); delay (10); } for (uint16_t x = ledtahomax; x > ledtaho; x--) { colors[x] = rgb_color(0, 0, 0); ledStrip.write(colors, ledtahomax); delay (10); } } void sens() { RPM=abs(120/((float)(micros()-lastflash)/1000000)); //расчет lastflash=micros(); //запомнить время последнего оборота } ===============================================
Если функция map() действительно такая: Код (C++): long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } То тут никак не обрабатывается выход за границы и соответственно значения вне границы. Можно после map использовать constrain() Код (C++): GREEN = constrain(GREEN,255,1)
ORLENOK прав, функция map() занимается только преобразованием диапазонов. Обеспечить контроль границ диапазона - заботы программиста (в данном случае проще всего взять constrain()).