# Can I please get some assistance with keeping an analog needle in the gauge

Hey guys and girls, This is my first project and ive been really reluctant to ask for help because of pride and its all been going along so smoothly. well up until about 3 days ago, so ive bitten the bullet and here i am asking for help Problem:
On my gauges, I cant seem to get the needle calibrated to the max and min range i want displayed on the analog display, the needle goes off the screen with excessive revolutions… ive been trying to fix it for days but im a bit unsure where to look, most of the resources are in regards to mapping sensors i’ve tried just about everything i can think of

What im trying to do:
have a working instrument cluster for a RC car where the speed and RPM gauge reacts to channel 1 and the temp and fuel gauge react to channel 0 (will be changed to a volt meter and temp sender down the track)

-have the rpm/speed gauge read 0rpm/0mph when there is no PWM signal (simulate engine off)
-with a pwm signal, have the gauge start reading from 900rpm to simulate a engine idling.

• a scale of 1500-2000pwm so that the RPM and speed gauge only react to trigger pulls on the TX and wont sent the needle back of the gauge when reverse or brakes are applied (1000-1500pwm)

here is my code… forgive me as it may be the worst u have seen?, this is my first project so hopefully it will get better lol

I think the problem is the loop, Ive tried to learn by coping peoples tutorials but i think its ended up as a big jumbled mess

here is the loop and ive attached the full code

``````oid loop() {

p = ch;                                                 //get value from ch 0
w = map(p,0,1023,1400,2000);                                    //map it between 1400 and 2000
m = map(p,0,1023,1400,1900);                                    //map needle movement
//show needle and dial for RPM gauge
rpm = m;                                                   //135 = zero position, 180 = just before middle, 0 = middle, 45 = max
if (rpm<45){                                               //positie correctie
rpm=rpm+135;
}
else {
rpm=rpm-45;
}

p1 = ch;                                                // get value from ch 0
w1 = map(p1,0,1023,1400,2000);                                 // map it between 1400 and 2000
m1 = map(p1,0,1023,1400,1900);                                  // map needle movement

// show needle and dial for fuel gauge
fuel = m1;                                                 // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
if (fuel<45){                                              // positie correctie
fuel=fuel+135;
}
else {
fuel=fuel-45;
}

p2 = ch;                                                // get value from ch 1
w2 = map(p2,0,1023,1400,2000);                                  // map it between 1400 and 2000
m2 = map(p2,0,1023,1400,1900);                                  // map needle movement

// show needle and dial for speed gauge
sped = m2;                                                 // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
if (sped<45){                                              // positie correctie
sped=sped+135;
}
else {
sped=sped-45;
}

p3 = ch;                                                // get value from ch 0
w3 = map(p3,0,1023,1400,2000);                                 // map it between 1400 and 2000
m3 = map(p3,0,1023,1400,1900);                                  // map needle movement

// show needle and dial for temp gauge
temp = m3;                                                 // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
if (temp<45){                                              // positie correctie
temp=temp-180;
}
else {
temp=temp+45;
}

ch = pulseIn(2, HIGH);                              //set pin 2 to ch
ch = pulseIn(3, HIGH);                              //set pin 3 to ch
ch = pulseIn(4, HIGH);                              //set pin 4 to ch
ch = pulseIn(5, HIGH);                              //set pin 5 to ch
ch = pulseIn(6, HIGH);                              //set pin 6 to ch
ch = pulseIn(7, HIGH);                              //set pin 7 to ch
Serial.print(ch);                                   //print ch1 to serial monitor
Serial.print(" - ");                                   //print - between channels
Serial.print(ch);                                   //print ch1 to serial monitor
Serial.print(" - ");                                   //print - between channels

u8g.firstPage();
do
{
u8g.drawBitmapP( 0, 0, 16, 15, lefticon);           //draw left icons
rpmgauge(rpm);                                      //draw RPM gauge
fuelgauge(fuel);                                   //draw fuel gauge
}
while(u8g.nextPage());

u8g.firstPage();
do
{
u8g.drawBitmapP( 0, 0, 16, 15, righticon);         //draw right icons
speedgauge(sped);                                 //Draw speed gauge
tempgauge(temp);                                  //draw temp gauge
}
while(u8g.nextPage());

}
``````

last progress photo, Right side has yellow icons now On my gauges, I cant seem to get the needle calibrated to the max and min range i want displayed on the analog display

Er… do I have this right:
Looking at your rpm gauge, it seems that rpmgauge(angle) would draw a needle at ‘0’ for 135, at ‘4’ for 180 (or 0) and ‘8’ for 45 ?? That’s a range of 90 degrees to cover 180 degrees of graphic gauge ?

Anyway, I suppose you have some value ‘p’ read from channel 1 that you want to turn into this odd ‘angle’ to drive the rpmgauge().

I’m not sure what the range of values are from channel 1, lets say it’s 0 to 1023.

If only part of that range is useful, you want to constrain() the value to that range.

For example, if values 100 to 1000 are the useful range, do:
useful= constrain( p, 100, 1000 );

Then you want to scale this range of values into the range of degrees for the gauge: the gauge has ‘90 degrees’ of range so:
usefulDegrees= map( useful, 100, 1000, 0, 90 );

You then have a number from 0 to 90.

For the (slightly odd) gauge drawing function you want that to be 135 - 180, 0 - 45

so:

gaugeAngle= usefulDegrees + 135; // now we have 135 to 225

• if( gaugeAngle > 180 )*
• gaugeAngle = gaugeAngle - 180; // 135-180, 0 - 45*

Yours,
TonyWilk

There is some confusing stuff going on here:

``````  p = ch;                                                 //get value from ch 0
w = map(p,0,1023,1400,2000);                                    //map it between 1400 and 2000
m = map(p,0,1023,1400,1900);                                    //map needle movement
//show needle and dial for RPM gauge
rpm = m;                                                   //135 = zero position, 180 = just before middle, 0 = middle, 45 = max
if (rpm<45){                                               //positie correctie
rpm=rpm+135;
}
``````

ch doesn’t get populated until later in loop, so on the first iteration, using it to assign to p is not a good idea. It’ll be fixed when loop is called again, but it’s a minor issue.

ch is (I think) a standard servo signal, so I’d expect it to be in the 1000 to 2000 microsecond range. It looks like the use of map means you’re treating it as if it was between 0 and 1023, as if it had come from analog read.

The next segment using rpm suggests that you’re expecting rpm to be between 0 and 180, but that’s unlikely because you mapped it to somewhere between 1400 and 1900 although even that’s dubious because it was likely not in the 0-1023 range.

I’d suggest that you concentrate on rpm for now and serial print the values of ch, p and rpm. Forget the other gauges until you square away the first calc.