Math not adding up

I'm guessing it has something to do with the way I've declared (or not) the variables, but arithmetic formulas that work for me in similarly coded javascript produce numbers in my sketch that don't match up.

Trying a simple multiplication function gives me negative numbers when I print them out to the serial monitor. I'm working with Adafruit's neopixels, so I'm calculating brightness values from 0-255. In my sketch, I'm changing the brightness of individual colors by first multiplying the existing value (always between 0 and 255) by a new brightness value (always between 0 and 255) then dividing by 255 to get a final number:

int rNew = (newBr*r)/255;
int gNew = (newBr*g)/255;
int bNew = (newBr*b)/255;

If I start outputting to the monitor, I'm seeing that, for example, if newBr=255 and r=255 I end up with rNew equaling -2. It should be right back to 255. I've defined all values as int. Is that wrong?

jedimasta: I'm guessing it has something to do with the way I've declared (or not) the variables, but arithmetic formulas that work for me in similarly coded javascript produce numbers in my sketch that don't match up.

Trying a simple multiplication function gives me negative numbers when I print them out to the serial monitor. I'm working with Adafruit's neopixels, so I'm calculating brightness values from 0-255. In my sketch, I'm changing the brightness of individual colors by first multiplying the existing value (always between 0 and 255) by a new brightness value (always between 0 and 255) then dividing by 255 to get a final number:

int rNew = (newBr*r)/255;
int gNew = (newBr*g)/255;
int bNew = (newBr*b)/255;

If I start outputting to the monitor, I'm seeing that, for example, if newBr=255 and r=255 I end up with rNew equaling -2. It should be right back to 255. I've defined all values as int. Is that wrong?

'int' is signed, so can only hold a 15-bit value plus sign bit. 255 x 255 = 65025 (16-bit) Try working with 'unsigned int'.

what are the datatypes of newBr and r ?

if they are an 8 bit type (byte char etc) the advice of OldSteve also applies.

all the other variables are set as int. I changed rNew, gNew, and bNew to unsigned int which helped quite a bit.

I’m certain the code can be improved, but aside from some potential timing problems that throw the integers off, it’s sorta working.

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6
//#define stripLength 10

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(stripLength, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

void setup() {
  Serial.begin(9600);
  randomSeed(analogRead(0));
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

int r = 255;
int g = 50;
int b = 0;
int brConstant = 255;
int dist;
int newBr;
int flameSpeed = 100; //larger = slower

void loop() {
flicker();
}

void flicker(){
//for(int i=0;i<stripLength;i++){
  int br= random(20,255);
  if(br>brConstant){
   dist = br-brConstant;
  }else{
   dist = brConstant-br;
  }
  int increment = dist/flameSpeed;
  for (int j=0;j<flameSpeed+1;j++){
    if(br<brConstant){
      newBr = brConstant - (increment*j);
     }else{
      newBr = brConstant + (increment*j);
    }
    unsigned int rNew = newBr*r;
    int rr = rNew/255;
    unsigned int gNew = newBr*g;
    int gg = gNew/255;
    unsigned int bNew = newBr*b;
    int bb = bNew/255;
    Serial.print(rr);
    Serial.print (" / ");
    Serial.print(gg);
    Serial.print (" / ");
    Serial.print(bb);
    Serial.println();
    strip.setPixelColor(0,rr,gg,bb);
    brConstant=br;
    Serial.println(br);
    strip.show();
    delay(0);  
   }
      //}
        
       // delay(0);
        }

The basic premise is is to create a candle flicker. I set the color of an LED to a medium-ish orange, then choose a random brightness (0-255) to gradually go to. Once the loop completes, it sets that final brightness as the new “target” brightness. Eventually, I’d like to randomize the speed of the steps, but I’m getting inconsistent fades, occasionally getting a random green color (red gets totally shut off).

If anyone has any suggestions, I’d love to hear them.

http://snippets-r-us.com/

"Do or do not; there is no try."

    delay(0);

Oh, aye.

[quote author=Nick Gammon date=1448180368 link=msg=2489554]

    delay(0);

Oh, aye. [/quote] That's the 'Claytons' delay - "the delay you have when you're not having a delay". Remember 'Claytons'?

Edit: 'Claytons' is/was a non-alcoholic beverage. For those too young to remember, the slogan was "The drink you have when you're not having a drink." (I think I'm giving my age away here. :D )

Make newBr vary from 0 to 256, then do:

byte rNew = (newBr*r) >> 8;

as shifting is cheaper than division.

[quote author=Nick Gammon date=1448180312 link=msg=2489552] http://snippets-r-us.com/

[/quote]

What is your full code?

Ethan :)