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 :frowning:

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[1];                                                 //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[0];                                                // 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[1];                                                // 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[0];                                                // 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[0] = pulseIn(2, HIGH);                              //set pin 2 to ch[0]
    ch[1] = pulseIn(3, HIGH);                              //set pin 3 to ch[1]
    ch[2] = pulseIn(4, HIGH);                              //set pin 4 to ch[2]
    ch[3] = pulseIn(5, HIGH);                              //set pin 5 to ch[3]
    ch[4] = pulseIn(6, HIGH);                              //set pin 6 to ch[4]
    ch[5] = pulseIn(7, HIGH);                              //set pin 7 to ch[5]
    Serial.print(ch[0]);                                   //print ch1 to serial monitor
    Serial.print(" - ");                                   //print - between channels
    Serial.print(ch[1]);                                   //print ch1 to serial monitor
    Serial.print(" - ");                                   //print - between channels
  
    I2C_SLA = 0x078;                                       //Display address
    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());
  
    I2C_SLA = 0x07A;                                      //Display address
    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

constrain

rcaddict84:
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[1];                                                 //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[1] 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[1] 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[1], p and rpm. Forget the other gauges until you square away the first calc.