mapping values

robtillaart:
You might use the multimap - Arduino Playground - MultiMap - as I assume you have some non linear mapping for the ultrasonic sensors.

yes, this is true, i have some non linear mapping.... but first i want to make it to work in linear, just to test the hardware....
I am thinking about smthing like this:

int left, right;			//lets assume this is the distance between the hand and the sensor in cm's
int %left, %right;			//percentage
int redbull, jagermeister;	//theese are the angles from 0 to 90 (corresponding to 0% and 100%) of the servo's

							//lets assume that the distance of reading is from 6 cm and 20 cm
							//so the left hand (20cm = 0%, 6cm = 100%), and right hand (6cm = 0% and 20cm = 100%)
							//and on the servos 90 is closed and 180 is open

if(right=13)							//right hand in the middle (13cm)
{
	//the ratio is 1:1 so servos depend only on left hand;
	servobull.write(180 * %left);
	servojager.write(180 * %left);
}

if(right<13)							//right hand goes bellow 13cm -->there will be more redbull than jagermeister
{
	redbull = map(right, 12, 6, 90, 180);
	jagermeister = map(right, 12, 6, 180, 90);
	servobull.write(redbull * %left);
	servojager.write(jagermaister * %left);
}

if(right>13)							//right hand goes above 13cm -->there will be more jagermeister than redbull
{
	redbull = map(right, 13, 20, 180, 90);
	jagermeister = map(right, 13, 20, 90, 180);
	servobull.write(redbull * %left);
	servojager.write(jagermaister * %left);
}

Wow, even reading that description I have no idea what the picture was supposed to mean.

I guess that your system has two taps and two sensors. Each tap will be controlled by a servo. One sensor will be used to set the proportion of two liquid. The other sensor will be used to set the flow rate (or quantity - I'm not sure which) of the resulting mixture.

Is that the sort of thing you're trying to achieve?

By the way, you can't use % in a variable name. You could use the word percent (or some abbreviation) instead.

I am thinking about smthing like this:

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

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??