mapping values

PaulS:

I am thinking about smthing like this:

You might think about something that actually compiles, instead. == instead of = in some places, too.

my question is do you understand what i need to do ?
and if it is, may you verify the code i wrote and suggest improvements ?

my question is do you understand what i need to do ?

Making the controller of a mixing machine my kids are not allowed to use ...

The code you post is only a snippet that does not compile, so it is hard to improve on that.

I don't know if the use of % characters in variables is acceptable,
I would prefer written version like percJagermeister as the % sign is the modulo operator in C++

The remark of PaulS is a valid one.
In C++ there is a difference in the "comparison equals ==" and the "assign equals ="

a statement
if (right = 13)
assigns the value 13 to the var right and after that it evaluates to true; so the block {} is executed.

robtillaart:

my question is do you understand what i need to do ?

Making the controller of a mixing machine my kids are not allowed to use ...

The code you post is only a snippet that does not compile, so it is hard to improve on that.

I don't know if the use of % characters in variables is acceptable,
I would prefer written version like percJagermeister as the % sign is the modulo operator in C++

The remark of PaulS is a valid one.
In C++ there is a difference in the "comparison equals ==" and the "assign equals ="

a statement
if (right = 13)
assigns the value 13 to the var right and after that it evaluates to true; so the block {} is executed.

k, thx, it wasn't my idea to make a compileable code in the first place...
but i only needed to figure out the regulation part... but now when i think i solved it, i need an extra feature:
I wan't to be able to "fool" the system when i remove my hands from the line of ultrasonic sensor, so it remembers the recent position of the hands... anyone got an idea?

P.S redbull and jegermaister were first things that came on my mind (idk. maybee cuz of that im asking you to solve my problems) :frowning:

anyone got an idea?

use an extra variable to hold this?

xvjeko:
k, thx, it wasn't my idea to make a compileable code in the first place...

However it's a good idea, nonetheless.

i appreciate your advice, but here's the new code, but i'm unable to verify it (because I don't have my hardware here)
but i would like if someone could skim trough the code and see if i made some stupidity (because i haven't programmed in months and because i'm not quite sure if i made right float to int conversions)...
Thanks, xvjeko

//Written for atmega328-PU (16MHz external crystal)
//Compiled with arduino 1.0 (www.arduino.cc)

#include <Servo.h>

#define BAUD 9600       //UART baud rate
#define ECHOPINL 9      //Echo pin l = left
#define ECHOPINR 11     //Echo pin r = right
#define MINPULSE 600    //Minimum servo pulse
#define MAXPULSE 2400   //Maximum servo pulse
#define TRIGPINL 10     //Trig pin l
#define TRIGPINR 12     //Trig pin r

Servo servol;           //Creating servo object servol
Servo servor;           //Creating servo object servor

int holdtime = 15;
bool hold = false;
int vall, valr;
float perl, perr;
float prevperl = 0, prevperr = 0;

int left(int d0, int d1)
{
  int cm;
  long duration;
  float percentage;
  digitalWrite(TRIGPINL, LOW);
  delay(2);
  digitalWrite(TRIGPINL, HIGH);
  delay(5);
  digitalWrite(TRIGPINL, LOW);
  duration = pulseIn(ECHOPINL, HIGH); 
  cm = microsecondsToCentimeters(duration);
  percentage = map(cm, d0, d1, 0, 100);
  return( (float)percentage / 100);
}

int right(int d0, int d1)
{
  int cm;
  long duration;
  float percentage;
  digitalWrite(TRIGPINR, LOW);
  delay(2);
  digitalWrite(TRIGPINR, HIGH);
  delay(5);
  digitalWrite(TRIGPINR, LOW);
  duration = pulseIn(ECHOPINR, HIGH); 
  cm = microsecondsToCentimeters(duration);
  percentage = map(cm, 20, 6, 90, 180);
  return( (float)percentage / 100);
}

long microsecondsToCentimeters(long microseconds)
{
  return microseconds / 29 / 2;
}

void debugg()
{
  Serial.print(vall);
  Serial.print(" ");
  Serial.print(valr);
  Serial.println();
}

void setup() 
{
  Serial.begin(BAUD);

  pinMode(ECHOPINL, INPUT);
  pinMode(ECHOPINR, INPUT);
  pinMode(TRIGPINL, OUTPUT);
  pinMode(TRIGPINR, OUTPUT);
}

void loop() 
{
  perl = left(20, 6);
  perr = right(6, 20);

  if( (perl - prevperl) >= (5/100) )
  {
    perl = prevperl;
    hold=false;
  }

  if( (perr - prevperr) >= (5/100) )
  {
    perr = prevperr;
    hold=false;
  }

  vall = perl * 100;
  vall = (int)vall;
  valr = perr * 100;
  valr = (int)valr;

  vall = map(vall, 0, 100, 90, 180);
  valr = map(valr, 0, 180, 180, 90);

  servol.write(vall * perl);
  servor.write(valr * perl);
  if(hold==true) delay(holdtime);
  hold=true;
  debugg();
}

but i'm unable to verify it (because I don't have my hardware here)

You need a PC running the Arduino IDE, NOT an Arduino, to verify code.

Come back when you have done that!

PaulS:

but i'm unable to verify it (because I don't have my hardware here)

You need a PC running the Arduino IDE, NOT an Arduino, to verify code.

Come back when you have done that!

code is verified :blush:
i just need to know if i made right conversions of the data types (or if you know any good simulator that will let me simulate the program please give me a link)

int left(int d0, int d1)
{
  int cm;
  long duration;
  float percentage;
  digitalWrite(TRIGPINL, LOW);
  delay(2);
  digitalWrite(TRIGPINL, HIGH);
  delay(5);
  digitalWrite(TRIGPINL, LOW);
  duration = pulseIn(ECHOPINL, HIGH); 
  cm = microsecondsToCentimeters(duration);
  percentage = map(cm, d0, d1, 0, 100);
  return( (float)percentage / 100);
}

You know that variables can have meaningful names, right? What do d0 and d1 mean?

Since percentage IS a float, why do you need to cast it to a float?

Why IS percentage a float? The map() function does not return a float.

There is no reason to use floats at all, since the function is going to truncate the value to an integer anyway.

How do left() and right() differ? Only in the pin numbers that they use. Create ONE function that is passed the pin number(s) to use. Half as much code to debug that way.

float perl, perr;

  perl = left(20, 6);
  perr = right(6, 20);

So, you have a function that returns an int. You store that value in a float. Why?

You are using a lot of global variables in just one function. Knock that off. Learn about scope and how to minimize it. Learn about static variables where you want a variable to retain its value between calls to the function.

Learn to match function return values to variables used to hold the return value. Make up your mind whether you need percentage or something else. You seem to be converting from percentage to ratio and back uselessly.

new version (saved about 50 lines in .hex file :))

//Written for atmega328-PU (16MHz external crystal)
//Compiled with arduino 1.0 (www.arduino.cc)

#include <Servo.h>

#define BAUD 9600       //UART baud rate
#define ECHOPINL 9      //Echo pin l = left
#define ECHOPINR 11     //Echo pin r = right
#define MINPULSE 600    //Minimum servo pulse
#define MAXPULSE 2400   //Maximum servo pulse
#define TRIGPINL 10     //Trig pin l
#define TRIGPINR 12     //Trig pin r

Servo servol;           //Creating servo object servol
Servo servor;           //Creating servo object servor

int holdtime = 15;
bool hold = false;
int vall, valr;
int perl, perr;
int prevperl = 0, prevperr = 0;

int sonic(int sensore, int sensort, int mincm, int maxcm)
{
  int per;
  long duration;
  digitalWrite(sensort, LOW);
  delay(2);
  digitalWrite(sensort, HIGH);
  delay(5);
  digitalWrite(sensort, LOW);
  duration = pulseIn(sensore, HIGH); 
  per = ms_cm(duration);
  per = map(per, mincm, maxcm, 0, 100);
  return(per);
}

long ms_cm(long ms)
{
  return ms / 29 / 2;
}

void debugg()
{
  Serial.print(vall);
  Serial.print(" ");
  Serial.print(valr);
  Serial.println();
}

void setup() 
{
  Serial.begin(BAUD);

  pinMode(ECHOPINL, INPUT);
  pinMode(ECHOPINR, INPUT);
  pinMode(TRIGPINL, OUTPUT);
  pinMode(TRIGPINR, OUTPUT);
}

void loop() 
{
  perl = sonic(ECHOPINL, TRIGPINL, 20, 6);
  perr = sonic(ECHOPINR, TRIGPINR, 6, 20);

  if( (perl - prevperl) >= 5 )
  {
    perl = prevperl;
    hold=false;
  }

  if( (perr - prevperr) >= 5 )
  {
    perr = prevperr;
    hold=false;
  }

  vall = map(vall, 0, 100, 90, 180);
  valr = map(valr, 0, 180, 180, 90);

  servol.write(vall * ((float)perl / 100) );
  servor.write(valr * ((float)perl / 100) );
  if(hold==true) delay(holdtime);
  hold=true;
  debugg();
}
  1. Is it better to use pointers or global variables?
  2. Is my

servol.write(vall * ((float)perl / 100) );

valid?
3. Are there any other major issues with my sketch?
Thanks all for help..

  1. Are there any other major issues with my sketch?

Yes, this one:

vall = map(vall, 0, 100, 90, 180);
  valr = map(valr, 0, 180, 180, 90);
  1. Is it better to use pointers or global variables?

Are apples or beach balls better? There is no real comparison. Pointers can be local or global. Global variables can be pointers or non-pointers.

  1. Is my
    Quote
    servol.write(vall * ((float)perl / 100) );
    valid?

Rather than casting an int to a float, it would be cleaner to simply divide by a float (100.0) rather than an int (100).

AWOL:

  1. Are there any other major issues with my sketch?

Yes, this one:

vall = map(vall, 0, 100, 90, 180);

valr = map(valr, 0, 180, 180, 90);

must have slipped through, thanks

and talking about

Are apples or beach balls better? There is no real comparison. Pointers can be local or global. Global variables can be pointers or non-pointers.

at least I remember that we used pointers (in highschool) instead of global variables ...
and

Rather than casting an int to a float, it would be cleaner to simply divide by a float (100.0) rather than an int (100)

servol.write(vall * (perl / 100.0) );

right ?

thanks

at least I remember that we used pointers (in highschool) instead of global variables ...

For what?

For instance,

int vall, valr;
int perl, perr;
int prevperl = 0, prevperr = 0;

are all global variables that do not need to be. There are only referenced in loop().

How would you use pointers instead of global variables? I can't see that that makes sense. Just make these local variables.

Now, you do want the values in the last two to persist between calls to loop(), so they should be static.

PaulS:

at least I remember that we used pointers (in highschool) instead of global variables ...

For what?

For instance,

int vall, valr;

int perl, perr;
int prevperl = 0, prevperr = 0;



are all global variables that do not need to be. There are only referenced in loop().

How would you use pointers instead of global variables? I can't see that that makes sense. Just make these local variables.

Now, you do want the values in the last two to persist between calls to loop(), so they should be static.

but they would be declared over and over ( while(1) ), which makes no sense to me.....

but they would be declared over and over

So? It doesn't matter. Make them static, so that doesn't happen, if it makes you feel better. (It won't make the Arduino feel any better.)

PaulS:

but they would be declared over and over

So? It doesn't matter. Make them static, so that doesn't happen, if it makes you feel better. (It won't make the Arduino feel any better.)

yep got the point...

static int perl, perr;

but this

int prevperl = 0, prevperr = 0;

needs to be declared only the first time, will static also solve this problem??

needs to be declared only the first time, will static also solve this problem?

That is what static is meant for. Declaring variables that you will expressly reset every pass through loop as static doesn't really make sense.

PaulS:

needs to be declared only the first time, will static also solve this problem?

That is what static is meant for. Declaring variables that you will expressly reset every pass through loop as static doesn't really make sense.

Thank you PaulS, you helped me excessively.