Pages: [1]   Go Down
Author Topic: Create a proportional scale of numbers where 10 = 0 and 60 =255  (Read 821 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a sensor where the largest value I expect is 60 and the minimum is 10.  I have the code working but my leds never get very bright (255 is max brightness) or all the way off (10 is dim but not off).  The part of my code that pertains to the question looks like this.

  Serial.println(averageValue); // So I can see the reading
  for(int i = 0; i < 10; i++ ) {
    if (averageValue > 60)
    {
      averageValue = 60; // Limits high reading
    }
  leds.r = averageValue, leds.g = averageValue, leds.b=averageValue;
  }
  FastSPI_LED.show();

I would like to create a "scale" where 10 = 0 and 60 = 255 and all the numbers in between are proportional (ie. 10 = 0, 35 = 127.5, 60 = 255 and of course include all the other numbers in between)  I googled for a while but don't really even know what to call what I am looking for.

Thanks

Logged

California
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3447
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://arduino.cc/en/Reference/map
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 227
Posts: 14024
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


and you can use constrain(x, lower, upper)  to limit the value.  But be aware it is a macro....

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you both, the map was what I was looking for makes prefect sense.  It seems when I try to constrain the arduino does weird things so I will work with that later.

  averageValue = map(averageValue,0,60,0,255);
  Serial.println(averageValue); // So I can see the reading
  for(int i = 0; i < 10; i++ ) {
    if (averageValue > 255)
    {
      averageValue = 255; // Limits high reading
    }
  leds.r = averageValue, leds.g = averageValue, leds.b=averageValue;
  }
  FastSPI_LED.show();
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50881
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
leds.r = averageValue, leds.g = averageValue, leds.b=averageValue;
I seriously doubt that this code is doing what you think it is. The comma operator is just about the most abused operator that C has. And, you are abusing it.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Then its taking a beating : ) the code seems to work fine; responds like intended.  There was actually a typo in my last post that particular line really looks like
Code:
leds[i].r = averageLevel, leds[i].g = averageLevel, leds[i].b=averageLevel;

im using the FastSPI library to control an RGB light strip, all 3 colors at the same level create a white light the sensor value just dims.  I am open to other methods if you have any, criticism by itself doesn't help anyone.

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50881
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
There was actually a typo in my last post that particular line really looks like
Those commas are SUPPOSED to be semicolons. Quit abusing the comma operator. Sooner or later, it WILL bite you in the ass.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
leds.r = averageValue, leds.g = averageValue, leds.b=averageValue;
I seriously doubt that this code is doing what you think it is.

It's unconventional and not IMO a good construct to use in this situation, but since the value of the expression is unused I would expect that to have the effect of making three assignments. I'd be surprised if that wasn't what the author expected.

And it's a mistake, which the author should correct now and make a mental note not to repeat. This sort of thing where you use the wrong construct which works by coincidence is very poor practice and WILL bite you on the arse.

You solution is not quite right according to your original post - you should be mapping between 10-60 not 0-60. The only way for the output of that map to exceed 255 is for the input to exceed 60. Is that likely?

Why are you assigning the same value to the LEDs ten times? Have you got one of those dodgy Arduinos where variable assignments sometimes don't work?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26626
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why are you assigning the same value to the LEDs ten times? Have you got one of those dodgy Arduinos where variable assignments sometimes don't work?
No, but another excellent illustration why we should always use CODE TAGS when posting code.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You solution is not quite right according to your original post - you should be mapping between 10-60 not 0-60. The only way for the output of that map to exceed 255 is for the input to exceed 60. Is that likely?
  My mistake , yes the mapping should go between 10 and 60.  The limit may exceed 60 so I just put an if statement to keep it at 60.
Quote
Why are you assigning the same value to the LEDs ten times? Have you got one of those dodgy Arduinos where variable assignments sometimes don't work?
each led on the strip has a numerical assignment 0,1,2,3 etc.. thats a loop that assigns each LED to act the same.  I posted the full code below in case anyone was interested... this is the first day hour number 3 that I've worked with this stuff so don't expect perfection.

Code:
int sensorPin = 0;

// an array to hold a bunch of sensor values for an average
int sampleSize = 40; // n readings 0 .. (n - 1)
int sensorReadings[39]; // n readings
int sampleCount = 0;
long sensorValue;

#include <FastSPI_LED.h>

#define NUM_LEDS 32

// Sometimes chipsets wire in a backwards sort of way
struct CRGB { unsigned char b; unsigned char r; unsigned char g; };
// struct CRGB { unsigned char r; unsigned char g; unsigned char b; };
struct CRGB *leds;

#define PIN 4

void setup()
{
  Serial.begin(9600);
  // set our inital setPoint to something
  int setPoint = 50;
 
  // init out our sensorReadings array
  int i;
  for (i = 0; i < sampleSize; i++) {
    sensorReadings[i] = setPoint;
  }
    FastSPI_LED.setLeds(NUM_LEDS);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_TM1809);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_HL1606);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_595);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_WS2801);

  FastSPI_LED.setPin(PIN);
  FastSPI_LED.setDataRate(3);
  FastSPI_LED.init();
  FastSPI_LED.start();

  leds = (struct CRGB*)FastSPI_LED.getRGBData();
}

void loop() {
 delay (20);
 
  sensorValue = analogRead(sensorPin);
 
  // store the current value in our readings array
  sensorReadings[sampleCount] = sensorValue;
 
  // sampleCount starts life at 0, then loops through sampleSize
  if (sampleCount == sampleSize) {
    sampleCount = 0;
  } else {
    sampleCount++;
  }
 
  // figure out the average sensor value
  int i;
  int sensorSum = 0;
  int averageValue = 0;
  int averageLevel = 0;
  for (i = 0; i < sampleSize; i++) {
    sensorSum = sensorSum + sensorReadings[i];
  }
  averageValue = sensorSum / sampleSize;
  Serial.println(averageValue);
  averageLevel = map(averageValue,12,49,0,255); // as I move the sensor the min/max values change so that is why they aren't consistent with the questions earlier.
  Serial.println(averageLevel);
 
  for(int i = 0; i < 10; i++ ) {

  leds[i].r = averageLevel, leds[i].g = averageLevel, leds[i].b=averageLevel;

  }
  FastSPI_LED.show();
}


Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this is the first day hour number 3 that I've worked with this stuff so don't expect perfection.

I don't expect perfection, but you're still ignoring this problem which has been pointed out repeatedly:
Code:
  leds[i].r = averageLevel, leds[i].g = averageLevel, leds[i].b=averageLevel;
Should be:
Code:
  leds[i].r = averageLevel; leds[i].g = averageLevel; leds[i].b=averageLevel;
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

le fixed

Code:

int sensorPin = 0;

// an array to hold a bunch of sensor values for an average
int sampleSize = 40; // n readings 0 .. (n - 1)
int sensorReadings[39]; // n readings
int sampleCount = 0;
long sensorValue;

#include <FastSPI_LED.h>

#define NUM_LEDS 32

// Sometimes chipsets wire in a backwards sort of way
struct CRGB { unsigned char b; unsigned char r; unsigned char g; };
// struct CRGB { unsigned char r; unsigned char g; unsigned char b; };
struct CRGB *leds;

#define PIN 4

void setup()
{
  Serial.begin(9600);
  // set our inital setPoint to something
  int setPoint = 50;
 
  // init out our sensorReadings array
  int i;
  for (i = 0; i < sampleSize; i++) {
    sensorReadings[i] = setPoint;
  }
    FastSPI_LED.setLeds(NUM_LEDS);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_TM1809);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_LPD6803);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_HL1606);
  //FastSPI_LED.setChipset(CFastSPI_LED::SPI_595);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_WS2801);

  FastSPI_LED.setPin(PIN);
  FastSPI_LED.setDataRate(3);
  FastSPI_LED.init();
  FastSPI_LED.start();

  leds = (struct CRGB*)FastSPI_LED.getRGBData();
}

void loop() {
 delay (20);
 
  sensorValue = analogRead(sensorPin);
 
  // store the current value in our readings array
  sensorReadings[sampleCount] = sensorValue;
 
  // sampleCount starts life at 0, then loops through sampleSize
  if (sampleCount == sampleSize) {
    sampleCount = 0;
  } else {
    sampleCount++;
  }
 
  // figure out the average sensor value
  int i;
  int sensorSum = 0;
  int averageValue = 0;
  int averageLevel = 0;
  for (i = 0; i < sampleSize; i++) {
    sensorSum = sensorSum + sensorReadings[i];
  }
  averageValue = sensorSum / sampleSize;
  Serial.println(averageValue);
  averageLevel = map(averageValue,12,49,0,255);
  Serial.println(averageLevel);
 
  for(int i = 0; i < 10; i++ ) {

  leds[i].r = averageLevel; leds[i].g = averageLevel; leds[i].b=averageLevel;
  }
  FastSPI_LED.show();
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 653
Posts: 50881
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Consistency is a good habit to develop early.
Code:
  int i;
  for (i = 0; i < sampleSize; i++) {

  int i;
  for (i = 0; i < sampleSize; i++) {

  for(int i = 0; i < 10; i++ ) {
For the record, I prefer the last version, with the declaration of i INSIDE the statement.

Code:
  leds[i].r = averageLevel; leds[i].g = averageLevel; leds[i].b=averageLevel;
I also prefer ONE statement per line.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I appreciate the help and best practices, looking forward to contributing some day.
Logged

Pages: [1]   Go Up
Jump to: