Hardware timer and interrupts issue


hello everyone,

i started programming arduino , and i'm making project read rpm , speed of car using arduino uno. far got working speed value not show properly. have used 1 hardware counter , 2 interrupts in project.

1. timer 1 on pin 5 - count pulses car's ecu calculate speed.
2. int0 on pin 2 - read ignition pulse calculate rpm.
3. int1 on pin 3 - 5v in headlight switch control brightness of display (max729 7 seg 8 digit).

i can proper reading rpm , brightness control working properly. here codes below.

code: [select]

#include <ledcontrol.h>

// inputs: din pin, clk pin, load pin. number of chips
ledcontrol display = ledcontrol(12, 10, 11, 1);

//speedo-----------------------------------------------------------
const int hardwarecounterpin = 5;
const int sampleperiod = 1000; //in milliseconds
const float pulsespermile = 4000; // pulses per mile toyota. other cars different.
const float convertmph = pulsespermile/3600;
unsigned int count;
float mph;
int kph;
int roundedkph;
int previouskph;
int prevcount;
//----------------------------------------------------------------

//rpm-------------------------------------------------------------
//configuration tachometer variables
const int sensorpin = 2;
const int sensorinterrupt = 0;
const int timeoutvalue = 5;
volatile unsigned long lastpulsetime;
volatile unsigned long interval = 0;
volatile int timeoutcounter;
int rpm;
int rpmlast = 3000;
int rpm_interval = 3000;
//---------------------------------------------------------------

//brightness control---------------------------------------------
int brightnessindicator = 13;  //light pin 13 led show brightness control in action.
int brightnessin = 3;  //sensor in headlight positive wire control brightness.
//---------------------------------------------------------------

void setup(void) {
 //serial.begin(9600);
 
 display.shutdown(0, false);  // turns on display
 display.setintensity(0, 10); // 15 = brightest
 printtrueno(); //print car's name
 delay(3000);
 inittozero(); //print zeros before going loop
 
 tccr1a = 0; //configure hardware counter
 tcnt1 = 0;  // reset hardware counter zero
 
 //config tach
 pinmode(sensorpin, input);
 attachinterrupt(sensorinterrupt, &sensorisr, rising);
 lastpulsetime = 0;
 timeoutcounter = 0;
 
 //config brightness control
 pinmode(brightnessindicator, output);  //led output
 pinmode(brightnessin,input);  //sensor in
 attachinterrupt(1, changebrightness, change);  //attach 2nd interrupt
 changebrightness();  //check head lights on or not.
}

void loop() {
 //speedo-----------------------------------------------------------
 // uses hardware pulse counter on arduino.
 // collects samples 1 second.
 bitset(tccr1b, cs12); // start counting pulses
 bitset(tccr1b, cs11); // clock on rising edge
 delay(sampleperiod); // allow pulse counter collect sampleperiod
 tccr1b = 0; // stop counting
 count = tcnt1; // store hardware counter in variable
 tcnt1 = 0;     // reset hardware counter zero
 mph = (count/convertmph)*10; // convert pulse count mph. 10x allows retaining 10th of mph resolution.
 kph = ((unsigned int) mph)*1.6; // convert kph , cast integer.

 int x = kph / 10;
 int y = kph % 10;
 
 // round whole mile per hour
 if(y >= 5){
   roundedkph = x + 1;
 }
 else {
   roundedkph = x;
 }
 
 //if kph less 1 kph show 0kph.
 //readings of 0.9kph or lower erratic , can
 //occasionally triggered electrical noise.
 //if(x == 0){
 if(x < 2){  // 1 triggered noise signal.
   roundedkph = 0;
 }
 
 // don't display kph readings more 50 kph higher previous reading because spurious reading.
 if(roundedkph < 181){
   if((roundedkph - previouskph) > 50) {
     serial.println(previouskph);
     printnumber(previouskph, 0);
   }
   else {
     serial.println(roundedkph);
     printnumber(roundedkph, 0);
   }
 }
 
 previouskph = roundedkph; // set previousmph use in next loop.
 //-----------------------------------------------------------------
 
 //rpm--------------------------------------------------------------
 if(rpm >= 0) {  //remove minus values  
   
   //let's keep rpmr value under control, between 0 , 9999
   rpm = constrain (rpm, 0, 9999);

   //if engine not running, print 0
   if ((micros() - lastpulsetime) < 5e6 ) {
     rpm = rpm;
   }
   else {
     rpm = 0;
   }
   
   if (rpm < 250)
     rpm = 0;
   //serial.println(rpm);
   printnumber(rpm, 1);
 }
 //-----------------------------------------------------------------
}

//each time interrupt receives rising tach signal, it'll run subroutine
void sensorisr() {
 unsigned long = micros();
 interval = - lastpulsetime;
 if (interval > 5000){
    rpm = 61000000ul/(interval * 2);
    lastpulsetime = now;
 }
}

void changebrightness() {
 int val = digitalread(brightnessin);  //read sensor value
 
 if(val == 1){  //if headlights on, pin goes high.
   digitalwrite(brightnessindicator, high);   //turn led on
   display.setintensity(0, 6); //reduce brightness.
 }
 else {
   digitalwrite(brightnessindicator, low);    //turn led off
   display.setintensity(0, 14);  //increase brightness.
 }
}

void printnumber(int v, int flag) {
   int ones;
   int tens;
   int hundreds;
   int thousands;
   
   if (flag==0){
     ones = v%10;
     v = v/10;
     tens = v%10;
     v= v/10;
     hundreds = v;

     //now print number digit digit
     if (hundreds>0)
       display.setdigit(0,0,(byte)hundreds,false);
     else
       display.setchar(0,0,' ',false);
       
     display.setdigit(0,1,(byte)tens,false);      
     display.setdigit(0,2,(byte)ones,false);
   }
   else if (flag=1) {
     ones = v%10;
     v = v/10;
     tens = v%10;
     v = v/10;
     hundreds = v%10;
     v = v/10;
     thousands = v%10;

     //now print number digit digit
     display.setdigit(0,4,(byte)thousands,false);
     display.setdigit(0,5,(byte)hundreds,false);
     display.setdigit(0,6,(byte)tens,false);
     display.setdigit(0,7,(byte)ones,false);
   }
}


i think problem between timer1 , first interrupt.   :smiley-eek-blue: can please me solve this?

thank much.

i can't figure out code impression is unnecessarily complicated simple task.

why not have isr sensor count every pulse , every second or see how many new pulses there have been , work out speed pulses/second

there doesn't seem need interrupt detect headlights on situation - not change rapidly.

something this

code: [select]
void loop() {
  curmillis = millis();
  checkheadlights();
  updaterpm();
  displayrpm();
}

void checkheadlights() {
   headightstatus = digitalread(headlightpin);
}

void updaterpm() {
   if (curmillis - prevmillis >= 1000) {
        prevmillis += 1000;
        currentrpmcount = rpminterruptcount;
        rpmticspersec = currentrpmcount - prevrpmcount;
        prevrpmcount = currentrpmcount;
   }
}

void rpmisr() {
  rpminterruptcount ++;
}


...r


Arduino Forum > Using Arduino > Programming Questions > Hardware timer and interrupts issue


arduino

Comments

Popular posts from this blog

Connecting Raspberry Pi 2 to P10(1R)-V706 LED Dot Matrix - Raspberry Pi Forums

TypeError: <unknown> is not a numpy array - Raspberry Pi Forums

datso and removing imagetitle - Joomla! Forum - community, help and support