# Double arithmetic [SOLVED]

Hi,

I’m a beginner but usually can work my way trough… I need some help though.

On an arduino uno I want to control an rgb led with hsv. I have found this library GitHub - mathertel/OneButton: An Arduino library for using a single button for multiple purpose input. which looks like is working.
I want to dim my led via the v value in the hsv then convert to rgb for the analogWrite.

Problem is this library wants double as variable for v.
And my code is not working.

``````for (double x = 0.00; x <= hsv[3]; x + 0.01){
serialPrint(x);
``````

The program never exit the for loop and x never increases… Always print out 0.00

I would appreciate some help!

It might work better with this:

``````for (double x = 0.00; x <= hsv[3]; x += 0.01){
``````

Pete

Your for loop needs an integer initializer to specify how many times it needs to iterate.
See Arduino reference page for details.

``````  for (int i = 0; i <= hsv[3]; i++) {
x += 0.01;
Serial.print(x);
}
``````

dlloyd:
Your for loop needs an integer initializer to specify how many times it needs to iterate.
See Arduino reference page for details.

``````  for (int i = 0; i <= hsv[3]; i++) {
``````

x += 0.01;
Serial.print(x);
}

The C for loop is much more flexible than for loops found in some other computer languages, including BASIC. Any or all of the three header elements may be omitted, although the semicolons are required. Also the statements for initialization, condition, and increment can be any valid C statements with unrelated variables, and use any C datatypes including floats. These types of unusual for statements may provide solutions to some rare programming problems.

Also the statements for initialization, condition, and increment can be any valid C statements with unrelated variables, and use any C datatypes including floats. These types of unusual for statements may provide solutions to some rare programming problems.

Wow - I didn't know that ... thanks! +1

You can use integer or float types in your loop, but the comparison really should match whatever the hsv[3] is that you are comparing it to.

el_supremo:
It might work better with this:

``````for (double x = 0.00; x <= hsv[3]; x += 0.01){
``````

Pete

Looks like it is working!
Many thanks

I’ve triet to search some knowildge about the operator you suggested but could’t find much… Do you have any pointers for it? I would like to learn something about it…

You didn't look very far

Thank you, I did see that page before, but reading it I couldn't get why I should use += instead of +

You guys helped me, it woks. But still I can't understand...

Also, on the same code I got more troubles. It hangs, and is now a few nights that I can't figure out why..

If you could have a look at this... http://forum.arduino.cc/index.php?topic=246837.msg1764575#msg1764575

x += y; is equivalent to x = x+ y;

In your original post you used x + 0.01 which is not the same as x = x + 0.01.

Pete

Right,
So if I would have wrote
for (double x = 0.00; x <= hsv[3]; (x + 0.01))

that would have worked?

No, that wouldn’t have worked - no assignment.

Got it now! ^_^

I got another question... I'm using this library https://github.com/adafruit/Adafruit_TCS34725 which uses Wire library to communicate via I2c.

I'm reading around a lot about wire library, and since I'm not using jumpers but about 10 meters cable to connect via I2c, plus I got this SSR to power up a switching power supply I suspect I may get a lot of noise to I2c connection... And for what I could understand the wire library doesn't like it very much.

Since my code is hanging, and I really suspect it does so while communicating via I2c, I would like to know which is the way to find out if this is the case... How can I check for I2c troubles???

What is hsv[3]? Does it even exist? Somehow, I seriously doubt it. My guess, without seeing all of your code, is that hsv is an array with 3 elements, indexed 0, 1, and 2. Therefore, hsv[3] is not in the array.

PaulS: What is hsv[3]? Does it even exist? Somehow, I seriously doubt it. My guess, without seeing all of your code, is that hsv is an array with 3 elements, indexed 0, 1, and 2. Therefore, hsv[3] is not in the array.

My code is all there, no reserves! You are right saying that hsv should normally have 3 elements. In this code I added a fourth one where to write the "value" part of hsv assigned from the pressled function. Most certainly there are much better ways to achieve this, but basically I'm using hsv[2] as initializer, just to make sure not to get rubbish data, then the "value" part comes from hsv[3].

My code is all there, no reserves!

Where? All I see is a few snippets.

In this code I added a fourth one where to write the "value" part of hsv assigned from the pressled function.

An array is for related data, like hue, saturation, and luminance. Whatever you are storing in the 4th element is NOT related.

Finally!!
Got it to work!!! No Hangs for the last 45 mins !!

The problem was in fact I2c…

Here my steps to solve the issue:

Comment out from twi.c library the two lines that enables pull up resistors for I2c. This is required as the Adafruit color sensor (flora version) run at 3V, and not 5 as the internal pull up.

Added 3k3 Ohm pull up resistors to each I2c pin on the arduino side.

Thats’it!! XD XD XD

Turns out as I thought that capacitance effects over the 10 meters I2c link (also running side by side with mains) mess up the signal.
I don’t know how or where (since I’m a newbie with electronics and programming and I still have to understand how libraries are made or works) but the Wire library messes everything up and wants to go in a loop with no way out.

tomy983:
Since my code is hanging, and I really suspect it does so while communicating via I2c, I would like to know which is the way to find out if this is the case… How can I check for I2c troubles???

Would have liked to know a way to find this out via software (serial maybe?).

The code is working but still if you would like to give me little help in making it look good (for the sake of learning) I would very much appreciate it!

PaulS:

My code is all there, no reserves!

Where? All I see is a few snippets.

It was linked earlier in the post, but will repost it here…

``````#include <avr/io.h>
#include <avr/wdt.h>

#define Reset_AVR() wdt_enable(WDTO_30MS)

#include <RGBConverter.h>
#include <Wire.h>
#include <OneButton.h>
//Outputs
#define relay1 6
#define relay2 7
#define redout 11
#define greenout 10
#define blueout 9
//Inputs
OneButton centroin(2, true);
OneButton ledin(3, true);
#define colorein 4
//Delay
#define dimspeed 50
//VAR
int relay1state = 0;
int relay2state = 0;
byte redstate = 0;
byte greenstate = 0;
byte bluestate = 0;

RGBConverter color;

double hsv[4];
byte rgb[3];

boolean direzdim = 0;
double dimdownstop = 0.10;

#define commonAnode false

// our RGB -> eye-recognized gamma color
byte gammatable[256];

void setup() {

if (tcs.begin()) {}
else {
Reset_AVR(); // halt!
}

//set led pin
pinMode(redout, OUTPUT);
pinMode(greenout, OUTPUT);
pinMode(blueout, OUTPUT);

rgb[0] = 100;
rgb[1] = 100;
rgb[2] = 100;
hsv[0] = 1.00;
hsv[1] = 0.50;
hsv[2] = 0.50;
hsv[3] = 0.50;

//set relay pin
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
//set button pin
pinMode(colorein, INPUT_PULLUP);

// link the myClickFunction function to be called on a click event.
centroin.attachClick(clickcentro);

ledin.attachClick(clickled);
ledin.attachDuringLongPress(pressled);
ledin.attachLongPressStop(stoppress);
// set onebutton times
centroin.setClickTicks(400);
ledin.setClickTicks(400);
ledin.setPressTicks(700);

// thanks PhilB for this gamma table!
// it helps convert RGB colors to what humans see
/* for (int i=0; i<256; i++) {
float x = i;
x /= 255;
x = pow(x, 2.5);
x *= 255;

if (commonAnode) {
gammatable[i] = 255 - x;
} else {
gammatable[i] = x;
}
//Serial.println(gammatable[i]);
}
*/  }

void loop() {
//listen to imput buttons
centroin.tick();
ledin.tick();
ledin.isLongPressed();

if ((digitalRead(colorein) == LOW) && (relay2state == 1)){
uint16_t clear, red, green, blue;
// turn on LED
tcs.setInterrupt(false);
delay(60);

tcs.getRawData(&red, &green, &blue, &clear);

// Figure out some basic hex code for visualization
uint32_t sum = clear;
float r, g, b;
r = red; r /= sum;
g = green; g /= sum;
b = blue; b /= sum;
r *= 256; g *= 256; b *= 256;

redstate =(int)r;// gammatable[(int)r];
greenstate =(int)g;// gammatable[(int)g];
bluestate =(int)b;// gammatable[(int)b];

//convert rgb to hsv
byte r1 = redstate;
byte g1 = greenstate;
byte b1 = bluestate;

color.rgbToHsv(r1,g1,b1,hsv);

color.hsvToRgb(hsv[0],hsv[1],hsv[3],rgb);
//rgb led output
analogWrite(redout, rgb[0]);
analogWrite(greenout, rgb[1]);
analogWrite(blueout, rgb[2]);

}
// turn off LED
tcs.setInterrupt(true);
delay(10);

}

//relay1 on and off
void clickcentro(){
if (relay1state == 0){
digitalWrite (relay1, HIGH);
relay1state = 1;
}
else {
digitalWrite (relay1, LOW);
relay1state = 0;
}
}

//relay2 on and off + rgb led dim on and dim off
void clickled(){

switch (relay2state){
case 0:
//DIMon
digitalWrite (relay2, HIGH);

relay2state = 1;

for (double x = 0.00; x <= hsv[3]; x += 0.01){
color.hsvToRgb(hsv[0],hsv[1],x,rgb);

analogWrite(redout, rgb[0]);
analogWrite(greenout, rgb[1]);
analogWrite(blueout, rgb[2]);

delay(dimspeed);
}
break;

case 1:
//DIMoff

double v;

for (v = hsv[3]; v >= 0.00; v -= 0.01){
color.hsvToRgb(hsv[0],hsv[1],v,rgb);

analogWrite(redout, rgb[0]);
analogWrite(greenout, rgb[1]);
analogWrite(blueout, rgb[2]);

delay(dimspeed);
}

digitalWrite (relay2, LOW);
relay2state = 0;

break;
}
}

// set rgb led brightness
void pressled(){//Serial.print("pressled");
if (direzdim == 0 && hsv[3] < 0.98){

for (double v = hsv[3]; v < 0.99 ; v += 0.01){
if (digitalRead (3)==LOW && relay2state == 1){
color.hsvToRgb(hsv[0],hsv[1],v,rgb);

hsv[3] = v;

analogWrite(redout, rgb[0]);
analogWrite(greenout, rgb[1]);
analogWrite(blueout, rgb[2]);

delay(dimspeed);
}
}
}

if (direzdim == 1 && hsv[3] > (dimdownstop + 0.01)){

for (double v = hsv[3]; v > dimdownstop; v -= 0.01){
if (digitalRead (3)==LOW && relay2state == 1){
color.hsvToRgb(hsv[0],hsv[1],v,rgb);

hsv[3] = v;

analogWrite(redout, rgb[0]);
analogWrite(greenout, rgb[1]);
analogWrite(blueout, rgb[2]);

delay(dimspeed);
}
}
}
}

// change brightness direction
void stoppress(){

if (direzdim == 0){
direzdim = 1;
}
else {
direzdim = 0;
}
}
//end
``````

Turns out as I thought that capacitance effects over the 10 meters I2c link

I haven’t checked for a long time, but I2C only used to be specced up to about 500mm (18 inches) - it was only mean for comms between chips on the same board (Inter-Integrated Circuit)

AWOL:

Turns out as I thought that capacitance effects over the 10 meters I2c link

I haven’t checked for a long time, but I2C only used to be specced up to about 500mm (18 inches) - it was only mean for comms between chips on the same board (Inter-Integrated Circuit)

Well yes but it is also used in other applications. Or not?

From wikipedia:
The maximum number of nodes is limited by the address space, and also by the total bus capacitance of 400 pF, which restricts practical communication distances to a few meters.