Jump to content

Arduino stuff/ programing/so cheap


flyingbrick

Recommended Posts

  • Replies 416
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Umm i can't edit the prior post to have

//high is turning the coil on  for 2ms and low turns it off & makes a spark.
//wait 10 milliseconds then turn the coil on again, saves much battery.

I do question why this doesn't compile


 

#define RPM_0        10
#define RPM_240      240
#define RPM_500      500
#define RPM_800      800
#define RPM_950      950
#define RPM_1100     1100
#define RPM_1250     1250
#define RPM_1400     1400
#define INCR_250   (RPM_240)
#define DECR_250   (RPM_240 - 5)
#define INCR_5     (RPM_240 + 50)
#define DECR_5     (RPM_500 - 5)
#define INCR_8     (RPM_500 + 50)
#define DECR_8     (RPM_950 - 5)
#define INCR_9     (RPM_800 + 150)
#define DECR_9     (RPM_1100 - 5)
#define INCR_11    (RPM_950 + 150)
#define DECR_11    (RPM_1250 - 5)
#define INCR_12    (RPM_1100 + 150)
#define DECR_12    (RPM_1400 - 5)
#define INCR_14    (RPM_1250 + 150)

enum rpmStates_t {IDLE = RPM_0, RPM_240, RPM_500, RPM_800, RPM_950, RPM_1100, RPM_1250, RPM_1400};
rpmStates_t curState, oldState;

Something about expected number before  #define 240 ?
But the one i based it on does..


#define TEMP_BAND     2
#define TEMP_MINOR    60
#define TEMP_GENERAL  75
#define TEMP_DIRE     90
#define INCR_MINOR    (TEMP_MINOR + TEMP_BAND)
#define INCR_GENERAL  (TEMP_GENERAL + TEMP_BAND)
#define INCR_DIRE     (TEMP_DIRE + TEMP_BAND)

#define DECR_IDLE     (TEMP_MINOR - TEMP_BAND)
#define DECR_MINOR    (TEMP_GENERAL - TEMP_BAND)
#define DECR_GENERAL  (TEMP_DIRE - TEMP_BAND)


 

  • Like 1
Link to comment
Share on other sites

you're creating 2 things called IDLE, one in warningStates_t and one in rpmState_t

you're also cant mix enums and defines like that. an enum is a set of numbers that increase by 1, so

enum test_t {STATEA, STATEB, STATEC, STATED};
will mean STATEA = 0, STATEB = 1, STATEC = 2 and STATED = 3 etc

so you're enums and defines wont work. What are you trying to do with them?

you also cant have multiple variables with the same names... curState and oldState are douibles as you made one with rpmStates_t and one with warningStates_t.
The compiler doesnt know/care that they are fifferent types, they have the same name, so it wont know which one you are talking about when you say oldState = IDLE; etc

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...
On 13/10/2019 at 19:47, Roman said:

Aahhhh so there's a new version of the Nextion screens out called the Intelligent Series.

https://nextion.tech/intelligent-series-introduction/

Can now use blending, transparencies, antialiased fonts, and a few other tricks.

So this means no more bitmaps for all of my text! haha.

So code will become a whole bunch less bloated and designing screens a lot easier too.

Looks like the refresh rate to the screen is a bit quicker too.

So this probably is enough to dump the idea of going to STM32 for now.

  • Like 2
Link to comment
Share on other sites

So as an example, if I want my text to change to a different colour because temp is high or whatever. 

Previously I needed to have a whole other set of bitmaps in that different colour. 

Where as now I can just change the colour in realtime.

Also with transparencies its not going to write every single friggen pixel in a square shaped bounding box to draw a needle for a gauge (or whatever)

So you can have parts that overlap in a bit of a nicer way without needing weird tricks to make it work. 

Should be good! main thing that I'm hoping for is the screen refresh rate to hopefully be a bit quicker.

Still might go to STM32 at some stage, I see theres a dev board available now for the baller spec version which will make things easier to start with.

https://www.st.com/en/evaluation-tools/stm32h757i-eval.html

Link to comment
Share on other sites

  • 4 weeks later...

Edit: Forgot to mention this is a nano 328P about 16.000hrtz?  If that makes a difference to the way it runs.
So.. this 

 

// constants won't change. Used here to set a pin number:
const int coil1 = 3;
const int coil2 = 5;
const int coil3 = 7;
const int coil4 = 9;

const int sensorPin1 = A4;
const int sensorPin2 = A1;
const int sensorPin3 = A2;
const int sensorPin4 = A3;

int sensorValue = 0;

int sensorThreshold = 200;
int sensorMax = 0; 

// Variables will change:
volatile int coilState = LOW;
volatile int coilPin = LOW;

volatile unsigned long currentMicros;
volatile unsigned long previousMicros = 0;        // will store last time LED was updated


// constants won't change:
const long interval = 1000;    
  
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

unsigned long dwell = 6000;        // will store last time LED was updated

// constants won't change:
const long coilCharge = 2000;           // interval at which to charge coil (Microseconds)

void setup() {
  // put your setup code here, to run once:
  pinMode(coil1, OUTPUT);
  pinMode(coil2, OUTPUT);
  pinMode(coil3, OUTPUT);
  pinMode(coil4, OUTPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
}

void activateCoilsIfLow(uint8_t inPin, uint8_t outPin)
{
 volatile unsigned long currentMicros = micros();
    
  if (analogRead(inPin) <= sensorThreshold)
  {
      while (coilState == LOW && coilPin == LOW) {
      coilState = HIGH;
      coilPin = HIGH;
      digitalWrite(outPin, !(digitalRead(outPin)));
      previousMicros = currentMicros;
     }
    while (coilState == HIGH && coilPin == HIGH && currentMicros - previousMicros >= coilCharge)
     {
      digitalWrite(outPin, LOW);
      coilPin = LOW;
      previousMicros = currentMicros;
     }
    while (coilState == HIGH && coilPin == LOW && currentMicros - previousMicros >= dwell)
    {
      previousMicros = currentMicros;
      coilState = LOW;
      coilPin = LOW;
    }
  }
  else
  {
    digitalWrite(outPin, LOW);
  }
}

void loop() {

  activateCoilsIfLow(sensorPin1, coil1);
  activateCoilsIfLow(sensorPin3, coil3);
  activateCoilsIfLow(sensorPin2, coil4);
  activateCoilsIfLow(sensorPin4, coil2);
}


runs really weird on manual advance mode, seems to lag at certain RPM, then suddenly the timing will become accurate for a slightly higher RPM, then lag for the few RPM above that.
Revving stationary it'll be fine at idle to ...1100RPM?  cough & pop out the carb' until 1700 RPM.
On the road you can feel it lurching at cruise speeds, each time the RPM rises or falls across that threshold that spans maybe... 10RPM layers where the lag disappears & re-appears, judging from the exhaust sound and gas temp' gauge reading 50-70 degrees above normal it's running retarded.  Feels like a cross between riding a horse and "Run out of gas & sloshing the last bit of fuel in the carb' bowl over the main jet" surging.
At 1600-1700 RPM or so it'll lose that lag & fire on time every time, feels like someone hit Vtec.
Tried changing micros to millis ect, same effect.  6,000 worked better than 10,000 micros.

Meanwhile. This crappy delay code will run perfectly.  But doesn't have any advance/retard (and if i tried to add that i'd lose lots of time to calculate it due to the delay...)

 


const int sensorPin1 = A4;
const int sensorPin2 = A1;
const int sensorPin3 = A2;
const int sensorPin4 = A3;
int sensorValue = 0;

int sensorThreshold = 200;
int sensorMax = 0; 

void setup() {
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
}

void activateCoilsIfLow(uint8_t inPin, uint8_t outPin)
{
  if (analogRead(inPin) <= sensorThreshold)
  {
    digitalWrite(outPin, !(digitalRead(outPin)));
    delay(2);
    digitalWrite(outPin, LOW);
    delay(10);
  }
  else
  {
    digitalWrite(outPin, LOW);
  }
}

void loop()
{

  activateCoilsIfLow(sensorPin1, 3);
  activateCoilsIfLow(sensorPin3, 7);
  activateCoilsIfLow(sensorPin2, 9);
  activateCoilsIfLow(sensorPin4, 5);
}
  • Like 2
Link to comment
Share on other sites

Maybe I'm missing something here but how does currentMicros get updated within the while loops?

Edit: Nevermind, just realised that this operates across calls to activateCoilsIfLow. Is there any point in guarding the second two while loops with the state of the input sensor once you've put the coil state into high? Maybe the input sensor state is changing and preventing the later two loops from being executed.

Link to comment
Share on other sites

Would it be on time? I think your misfiring is caused by the main execution loop having to cycle through all the other cylinders before coming back to the active coil and checking micros() as the while loops behave like if statements. Have you tested the frequency of the main execution loop? I know some of those Arduino library calls can be particularly slow which could be causing large lapses in time.

Link to comment
Share on other sites

Not sure how to test the frequency of the main loop without an oscilloscope so i had it serial print for 30 seconds.
Which told me the baud rate was the limiting factor.
E.G.

 

current milliseconds0


current loop count1
current milliseconds0
current loop count2
current milliseconds1
current loop count3
current milliseconds2
current loop count4
current milliseconds2
current loop count5
current milliseconds3
current loop count6
current milliseconds7
current loop count7
current milliseconds19
current loop count8
current milliseconds33
current loop count9
.......................

current milliseconds20272
current loop count1124
current milliseconds20291
current loop count1125
current milliseconds20311
current loop count1126
current milliseconds20331

At 9600


Versus

Edit: what happened to the text with the other rate ect?

Anyhow. adding "coilState = LOW" in the 'else' statement has transformed the open road running.  Work much like i intended  (Duhh what an oversight that was!)


Would drive fine.  But it's now hard to start & misses at 120-500 RPM?  Can't figure that one out.

 

  • Like 1
Link to comment
Share on other sites

Just try this..

void activateCoilsIfLow(uint8_t inPin, uint8_t outPin)
{
 volatile unsigned long timestamp = 0;
    
  if (analogRead(inPin) <= sensorThreshold){
  
    coilState = HIGH;
    coilPin = HIGH;
    digitalWrite(outPin, HIGH);
    
    timestamp = micros();
                                          
    while (coilState == HIGH && coilPin == HIGH && (timestamp + coilCharge) > micros());	//Busy wait
   
    digitalWrite(outPin, LOW);
    coilPin = LOW;
    timestamp = micros();

    while (coilState == HIGH && coilPin == LOW && (timestamp + dwell) > micros());

    coilState = LOW;
    coilPin = LOW;

  }
}

I'm not sure how long your trigger period is, whether an ignition cycle could repeat during one combustion cycle, or whether that would even matter.. but I assume this would do what you're intending your code to do.

Link to comment
Share on other sites

 

// constants won't change. Used here to set a pin number:
const int coil1 = 3;
const int coil2 = 5;
const int coil3 = 7;
const int coil4 = 9;

const int sensorPin1 = A4;
const int sensorPin2 = A1;
const int sensorPin3 = A2;
const int sensorPin4 = A3;

int sensorValue = 0;

int sensorThreshold = 200;
int sensorMax = 0;

// Variables will change:
volatile int coilState = LOW;
volatile int coilPin = LOW;

volatile int sparkTriggerDelayActive = false;     //added this to try & see if i can delay spark at low RPM.
volatile int sparkTriggerDelay = 0;
volatile unsigned long rpmCurrMicros= 0;
volatile unsigned long rpmOldMicros = 0;
volatile int sensor1TriggerCounter = 0;           // counter for the number of button presses
volatile int sensorTriggerState = false;         // current state of the button
volatile int lastsensorTriggerState = true;     // previous state  of the button/sensor in this case.

// constants won't change:
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store

const long dwell = 10;        // but this is how long the "points" are open, open longer reduces duty cycle of coils.

// constants won't change:
const long coilCharge = 2;           // interval at which to charge coil (milliseconds)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(coil1, OUTPUT);
  pinMode(coil2, OUTPUT);
  pinMode(coil3, OUTPUT);
  pinMode(coil4, OUTPUT);
  pinMode(A4, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
}

void activateCoilsIfLow(uint8_t inPin, uint8_t outPin)
{
 volatile unsigned long timestamp = 0;
   if (analogRead(inPin) <= sensorThreshold)
   sensorTriggerState = true;
   {
    if (lastsensorTriggerState = false)
    {
      timestamp = micros();
      if ((timestamp + sparkTriggerDelay) >= micros())
      {
        lastsensorTriggerState = true;
      }
    }
    else if (lastsensorTriggerState = true && analogRead(inPin) <= sensorThreshold)
     {
      coilState = HIGH;
      coilPin = HIGH;
      digitalWrite(outPin, HIGH);
    
      timestamp = millis();
                                          
      while (coilState == HIGH && coilPin == HIGH && (timestamp + coilCharge) > millis());  //Busy wait
   
     digitalWrite(outPin, LOW);
      coilPin = LOW;
      timestamp = millis();

      while (coilState == HIGH && coilPin == LOW && (timestamp + dwell) > millis());
 
      coilState = LOW;
      coilPin = LOW;
    }
  }
  else if (analogRead(inPin) >= sensorThreshold)
  {
    sensorTriggerState = false;
    if (sensorTriggerState != lastsensorTriggerState)
    {
      rpmOldMicros = rpmCurrMicros;
      rpmCurrMicros = micros();
      lastsensorTriggerState = false;
      rpmConsultRatioTable();
    }
  }
}

void loop() {
  activateCoilsIfLow(sensorPin1, coil1);
  activateCoilsIfLow(sensorPin3, coil3);
  activateCoilsIfLow(sensorPin2, coil4);
  activateCoilsIfLow(sensorPin4, coil2);
}

void rpmConsultRatioTable()
{
  if (rpmCurrMicros - rpmOldMicros >= 497512) //sub250rpm
    {
      sparkTriggerDelay =0;
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 255024) && (rpmCurrMicros - rpmOldMicros >= 169491)) //125rpm
    {
      sparkTriggerDelay =81000;                     //was 57, then 59
      Serial.print ( "RPM 125" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 169491) && (rpmCurrMicros - rpmOldMicros >= 127512)) //177rpm
    {
      sparkTriggerDelay =39000;
      Serial.print ( "RPM 177.5" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 127512) && (rpmCurrMicros - rpmOldMicros >= 85008)) //250rpm
    {
      sparkTriggerDelay =32000;                    //was 27  //at 250 RPM and 45 degree sensor advance, this would be 30ms to TDC, subtract 2ms for coil charging and subtract more m.s. for advance
      Serial.print ( "RPM 250" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 85008) && (rpmCurrMicros - rpmOldMicros >= 61000)) //375rpm
    {
      sparkTriggerDelay =18000;                 //was 16
      Serial.print ( "RPM 375" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 61000) && (rpmCurrMicros - rpmOldMicros >= 48000)) //500rpm
    {
      sparkTriggerDelay =13000;                 //was 11
      Serial.print ( "RPM 500" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 48000) && (rpmCurrMicros - rpmOldMicros >= 41000))  //625rpm
    {
      sparkTriggerDelay =7000;
      Serial.print ( "RPM 625" );
    }
  else if ((rpmCurrMicros - rpmOldMicros <= 41000) && (rpmCurrMicros - rpmOldMicros >= 31500)) //750rpm
    {
      sparkTriggerDelay =1670;
      Serial.print ( "RPM 750" );
    }
  else if (rpmCurrMicros - rpmOldMicros <= 31500) //just under 1000rpm
    {
      sparkTriggerDelay =0;
      Serial.print ( "RPM over 1000" );
    }
}


If i increment the math side of things by 100 it stays at full advance all the time.  By 1,000 - 10,000, same thing.  It even advances while sitting there not turning over, but will retard while running.
Please tell me how bad my math is.

  • Like 2
Link to comment
Share on other sites

  • 3 months later...
  • 1 month later...
  • 4 weeks later...

Been having a play with new Nextion screen and Teensy 4.0. 
Both of which are remarkably quicker than older stuff I was using. (But was still good)
This time around instead of using all of the premade features you can use in the screen GUI designer thing. Which are a bit limited and inflexible. 
I'm gonna make as many features as I can by "hand" so I started with an XY graph that's rescalable.

So to draw a graph on the screen you just need to specify where it is on the screen, how big it is, and which variables are on the X and Y axis. 
Then it looks up a table for that particular variable which shows what its min and max values should be. 
Then rescales everything to suit the size that the graph ends up being.

Benefit of doing it this way, is I can just manually add items to the screen in realtime and save the layout.
As well as being able to change which values its showing on X and Y axis, I can just save the settings to eeprom.
Rather than needing to do it via a combination of the screen GUI program and updating arduino code to match it. Zillions of hours left to go though. haha.

But most of the canbus code and my ignition trim code will be directly portable over to the Teensy 4.0 so that's good.
 

 
And then as per post in the EFI thread I made a little engine simulator thing, that will send/recieve canbus signals exactly how my ECU would. So I can use it as a simulator for testing my screen without having to go to the car to confirm. 
 


 

 

As my car doesnt go

 

 

Because I havent spent time finishing it

 

 

Because I've been wasting time on this instead

  • Like 2
  • Thanks 1
  • Haha 2
Link to comment
Share on other sites

  • 1 month later...

On the new truck (Landrover Defender) I have a few sensors to place around, temp, fluid levels etc to keep an eye on vitals that were never given from factory.

Having a dash full of gauges is not my cup of tea so i'm looking at wiring them to an arduino mega that then gives the option of a small display to manually select inputs and have an alarm system when things get bad.

Keen to run a couple of pt100/1000 sensors while there but can't find a shield that runs 0-5V output, anyone have a lead on options there?

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...