Hi I am trying to figure out how I can get multiple outputs from the function I have for creating 8-bit RGB values.
I am certain the current method does not work - will I need to create a structure? or global variable? please let me know what is the optimal way,I am pretty new to coding with C
//initializations
int k; //counter variable
int n = 3; //set to 256
//int iter = 3; //RGB columns
int Niter = n * n * n;
int Rval;
int Gval;
int Bval;
int redP = 7; //pinnumber
int blueP = 8; //pinnumber
int greenP = 9; //pinnumber
// function declaration
int vals[1][3];
void setup() {
Serial.begin(9600);
pinMode(redP, OUTPUT);
pinMode(blueP, OUTPUT);
pinMode(greenP, OUTPUT);
}
void loop() {
Rval = 0;
Gval = 0;
Bval = 0;
for (k = 1; k <= Niter; k = k + 1) {
analogWrite(blueP, Bval);
Serial.print(Bval);
Serial.print(" ");
analogWrite(greenP, Gval);
Serial.print(Gval);
Serial.print(" ");
analogWrite(redP, Rval);
Serial.println(Rval);
delay(10);
vals[1][3] = RGB(Bval,Gval,Rval,n); //problem is here; how do I extract the values
Bval = RGB[0];
Gval = RGB[1];
Rval = RGB[2];
}
delay(1000);
Serial.println("");
}
int RGB(int Bval, int Gval, int Rval, int n) {
if (Bval < (n - 1)) {
Bval = Bval + 1;
}
else {
Bval = 0;
}
val[1][1]= Bval;
if (Gval < (n - 1)) {
Gval = Gval + 1;
}
else {
Gval = 0;
}
val[1][2] = Gval;
if (Rval < (n - 1)) {
Rval = Rval + 1;
}
else {
Rval = 0;
}
val[1][3]=Rval;
}
groundFungus:
What value(s) do you want to return from which function?
val[1][1]= Bval;
val is not in scope. Is that supposed to be vals?
You should get a warning on the RGB function because it is supposed to return an int, but there is no return() in the function.
my bad;
val is supposed to be an array that consists the values for R, G and B - basically a 1x3 array - I am so used to python and MATLAB that I made that mistake. The returns should be the values for R G and B
J-M-L:
returning a struct is one way, but you can also pass parameters by reference or pointer and update those directly in the function
here is an example (run with Serial console at 115200 bauds)
void updateVariablesRef(int &a, int &b) // by reference
{
a = 12;
b = 13;
}
void updateVariablesPtr(int *a, int *b) // by pointer
{
*a = 56;
*b = 78;
}
void setup() {
Serial.begin(115200);
int v1 = 22, v2 = 33;
Serial.print(("\nBefore: ")); Serial.print(v1); Serial.write(' '); Serial.println(v2);
updateVariablesRef(v1, v2);
Serial.print(("After by reference: ")); Serial.print(v1); Serial.write(' '); Serial.println(v2);
updateVariablesPtr(&v1, &v2); // we pass the address of the variables
Serial.print(("After by Pointer: ")); Serial.print(v1); Serial.write(' '); Serial.println(v2);
}
void loop() {}
Serial Monitor (@ 115200 bauds) will show
Before: 22 33
After by reference: 12 13
After by Pointer: 56 78
so you can see the functions did their job
I am new to C, why would one set the address of a and b be beneficial -
coming from a background of Python and MATLAB - my go to solution was to create an array that will house the values for R,G and B for that single iteration.
thus val.
val tried to be a 1x3 array, but C does not work like that.
I want to grab the values, for R, G and B, from my function - then I would like to assign it to the Rval, Gval and Bval variables in my loop() function.
J-M-L:
Those were just simple example to show how parameters can be used to pass back values
==> look at the example with the structures then (in post #3).
I took your advice and read the structures documentation, I believe I made a valid tag to store my RGB values that a byte each (8-bit color). However, there seems to be an issue as the values are not being assigned. Do you believe my assignments are written wrong?
//initializations
int k; //counter variable
int n = 2; //set to 256
int Niter = n * n * n;
int Rval; //0-256 value for Red
int Gval; //0-256 value for Green
int Bval; //0-256 value for Blue
int redP = 7; //pinnumber for AnalogWrite
int blueP = 8; //pinnumber for AnalogWrite
int greenP = 9; //pinnumber for AnalogWrite
// structure declaration
struct RGB {
int R;
int G;
int B;
} RGBvals;
void setup() {
Serial.begin(115200);
pinMode(redP, OUTPUT);
pinMode(blueP, OUTPUT);
pinMode(greenP, OUTPUT);
}
void loop() {
Rval = 0;
Gval = 0;
Bval = 0;
for (k = 1; k <= Niter; k = k + 1) {
analogWrite(blueP, Bval);
Serial.print(Bval);
Serial.print(" ");
analogWrite(greenP, Gval);
Serial.print(Gval);
Serial.print(" ");
analogWrite(redP, Rval);
Serial.println(Rval);
delay(10);
Bval = RGBvals.B;
Gval = RGBvals.G;
Rval = RGBvals.R;
}
delay(1000);
Serial.println("");
}
int RGB(int Bval, int Gval, int Rval, int n) {
if (Bval < (n - 1)) {
Bval = Bval + 1;
}
else {
Bval = 0;
}
RGBvals.B= Bval;
if (Gval < (n - 1)) {
Gval = Gval + 1;
}
else {
Gval = 0;
}
RGBvals.G = Gval;
if (Rval < (n - 1)) {
Rval = Rval + 1;
}
else {
Rval = 0;
}
RGBvals.R=Rval;
}
The goal of this code is to create all the 8-bit color combinations for an RGB LED.
I know code for this exists but I want to write my own and struggle to learn C, it is different from the languages I am familiar with.
Basically, there is a nested for loop (with 3 for loops) that computes all 16 million possible combinations; the function RGB (which should be renamed to RGB_strength -i.e. how strong each LED lights up) aids in the creation of the values from 0 to 256.
I struggle to get the values to output from the RGB_strength function; I ran the same code in MATLAB and it works like a charm - but in C, I need structures for assignment.
...and I do not know why the values are all 0 0 0, I thought I initialized it by writing
// structure declaration
struct RGB {
int R=0;
int G=0;
int B=0;
} RGBvals;
this is my updated code- please point out what I am doing wrong
//////////////////initializations/////////////////////////////////////////////////////////
int k; //counter variable
int n = 2; //set to 256
int Niter = n * n * n;
int Rval; //0-256 value for Red
int Gval; //0-256 value for Green
int Bval; //0-256 value for Blue
int redP = 7; //pinnumber for AnalogWrite
int blueP = 8; //pinnumber for AnalogWrite
int greenP = 9; //pinnumber for AnalogWrite
// structure declaration
struct RGB {
int R=0;
int G=0;
int B=0;
} RGBvals;
///////////////////////SET-UP FUNCTION////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
pinMode(redP, OUTPUT);
pinMode(blueP, OUTPUT);
pinMode(greenP, OUTPUT);
}
/////////////////////LOOP FUNCTION//////////////////////////////////////////////////
void loop() {
Rval = 0;
Gval = 0;
Bval = 0;
for (k = 1; k <= Niter; k = k + 1) {
analogWrite(blueP, Bval);
Serial.print(Bval);
Serial.print(" ");
analogWrite(greenP, Gval);
Serial.print(Gval);
Serial.print(" ");
analogWrite(redP, Rval);
Serial.println(Rval);
delay(10);
//get the values created using RGB_strength - to be used in analogwrite
Bval = RGBvals.B;
Gval = RGBvals.G;
Rval = RGBvals.R;
}
delay(1000);
Serial.println("");
}
//////////////FUNCTION TO GET VALUES FOR EACH R,G,B////////////////////////////////////////////////////////////////////////////
int RGB_strength(int Bval, int Gval, int Rval, int n) {
if (Bval < (n)) {
Bval = Bval + 1;
}
else {
Bval = 0;
}
RGBvals.B= Bval;
if (Gval < (n)) {
Gval = Gval + 1;
}
else {
Gval = 0;
}
RGBvals.G = Gval;
if (Rval < (n)) {
Rval = Rval + 1;
}
else {
Rval = 0;
}
RGBvals.R=Rval;
}
And, if you want to "compute" all colors of an RGB LED, why not simply count from 0 to 0xFFFFFF (so 16777216 times) and split this number in 3 bytes ? Like this, for example
void loop()
{
static uint32_t color = 0;
uint8_t r = color & 0xFF;
uint8_t g = (color >> 8) & 0xFF;
uint8_t b = (color >> 16) & 0xFF;
analogWrite(redP, r);
analogWrite(greenP, g);
analogWrite(blueP, b);
color++;
}
how can I incorporate RGB_strength in my loop;
I really do not understand the assignment in C, I created a structure that houses the values. Could you tell me how I can fix it?
*I have been working on this for the past 2 days - I really would like to figure out what is wrong
hansherath:
I really do not understand the assignment in C
You keep talking about C, but Arduino uses C++, which is a different language.
Have you tried following a C++ tutorial? All of this stuff is covered in C++ books, courses and tutorials. A forum thread is not the right format to learn the basics of a programming language.
In the code that you posted in your previous message, you never call the function RGB_strength.
You need to call it whenever you want your global variable "RGBvals" to be updated
...
//get the values created using RGB_strength - to be used in analogwrite
RGB_strength(Bval, Gval, Rval, k);
Bval = RGBvals.B;
Gval = RGBvals.G;
Rval = RGBvals.R;
...
It should work, but it's really clumsy, not the proper way to do it
Did you see the simpler code in my previous message ?
PieterP:
You keep talking about C, but Arduino uses C++, which is a different language.
Have you tried following a C++ tutorial? All of this stuff is covered in C++ books, courses and tutorials. A forum thread is not the right format to learn the basics of a programming language.
guix:
In the code that you posted in your previous message, you never call the function RGB_strength.
You need to call it whenever you want your global variable "RGBvals" to be updated
...
//get the values created using RGB_strength - to be used in analogwrite
RGB_strength(Bval, Gval, Rval, k);
Bval = RGBvals.B;
Gval = RGBvals.G;
Rval = RGBvals.R;
...
It should work, but it's really clumsy, not the proper way to do it
Did you see the simpler code in my previous message ?
Thanks for the reply! It works now - I really appreciate it.
I am reading through your code; it is far more elegant. Thank you!
My code may be more elegant, but it probably doesn't do what you really want It will loop all colors, but slowly and not in a nice order
About your code, you don't need that "RGBvals" variable. Since the beginning of this topic you have been given the (or one) answer: you should use "references", which mean that you give the memory addresses of the variables to the function, so the function can directly modify the value of these variables, without making copies of them, and without having to return anything
Basically, there is a nested for loop (with 3 for loops) that computes all 16 million possible combinations; the function RGB (which should be renamed to RGB_strength -i.e. how strong each LED lights up) aids in the creation of the values from 0 to 256.
if you want three nested "for" loops you can do this
void loop()
{
for (int r = 0; r < 256; r++) {
analogWrite(redP, r);
for (int g = 0; g < 256; g++) {
analogWrite(greenP, g);
for (int b = 0; b < 256; b++) {
analogWrite(blueP, b);
}
}
}
}