Elektroniskt tändsystem med Arduino

Berätta om dina pågående projekt.
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Hej alla motorintresserade programmerare! Jag håller på med ett mycket förenklat Arduino elektroniskt tändssystem som avser ersätta brytarsystem på förgasarmotorer (veteranbilar och flygplan). Jag har utgått från en VW typ 1 motor som även används på flygplan (jag är flygtekniker). Detta projektet blev ett sätt för mig att fördjupa mig lite inom programmering eftersom jag läser till automationsingenjör nu (examen juni 2016).

Finns det någon där ute som kan hjälpa mig med mitt program och se om det går att göra ännu mer tillförlitligt och driftsäkert? Jag behöver även hjälp med hur jag ska testa systemet/programmet för att se att tändkurvan stämmer i verkligheten. Jag kan ju så klart testa på en motor direkt, men det tar lite tid. Jag funderar på att testa på gräsklipparen innan jag kör på en bilmotor.

Här är en video på min labbplatta med vevaxelsimulator (propellern) och två dioder som visar signalerna till tändboxen.
Det är anpassat för "smarta" wasted spark tändboxar (2 tändstift per spole) med inbyggd logik.

Jag bifogar ett utkast på en systembeskrivning och kod.

Koden är även här (uppdaterad 2016-01-19):

Kod: Markera allt

#include <Avr/interrupt.h>
#include <Avr/io.h>

//Pin definitions:
const byte HallPin1 = 2; // Pin nr 2  to Hall sensor
const byte HallPin2 = 3; // Pin nr 3 is also to Hall sensor
const int Ign1Pin = 8;  // (PORTB,0)
const int Ign2Pin = 11; // (PORTB,3)

volatile long int microseconds;          // The microsecondcounter value.
volatile unsigned int cranktime;         // Time from 3 degrees to where the coil should start to load.
volatile byte IgnSystem;                 // Statusword for active ign system.
volatile byte dwellTime;                 // The time the coil should charge (default is 0,004 seconds.

// RPM variables:
volatile byte half_revolutions;
volatile unsigned int rpm;
volatile unsigned int timeold;

/***********************************************************************/
void setup() {
  
  crankingDwellTime = 4000; //in uS
  runningDwelltime = 3000;  //in uS
  half_revolutions = 0;        
  rpm = 0;                     
  timeold = 0;                
  IgnSystem = 0;               // No ignition system is active.

  pinMode(Ign1Pin, OUTPUT);    // Initialize the Ignition 1 pin as an output.
  pinMode(Ign2Pin, OUTPUT);    // -"-
  digitalWrite(Ign2Pin, LOW);  // bitClear(PORTB, 3); Turn the ignition off in case it's on
  digitalWrite(Ign1Pin, LOW);  // bitClear(PORTB, 0);          //  -"-

  attachInterrupt(digitalPinToInterrupt(HallPin1), SensorOn, RISING);   //Hall sensor DI for Ignition 1
  attachInterrupt(digitalPinToInterrupt(HallPin2), SensorOff, FALLING); //-"- 2

  /********** Setup timer2*************/
  noInterrupts();
  TCCR2A = 0;               // Turn off Control register for waveform generation
  TCCR2B = 0;               // Turn off noise cancelling, turn off edge select, waveform gen mode 0, no clock source
  TCCR2A |= (1 << WGM21);   // Turn on CTC mode (so it will start again) automatically
  TIMSK2 |= (1 << OCIE2A);  // Set interrupt on compare match.
  OCR2A = 8;                // Prescaler of 64 gives 4uS per tick, 4uS * 8 = 32uS (32uS = 1 degree at ~5100rpm).
  TCNT2  = 0;               // Reset timer counter to 0
  microseconds = 0;         // Reset the ms counter variable.
  interrupts();
}
//========================================================================
/* The interrupt action for magnet 1: The Timer starts to count up 32 uS at a time.
**********************/
void SensorOn () {

  if ((rpm < 300) & (IgnSystem == 0)) {     // When cranking (starting), the coil nr 2 will charge at once.
    digitalWrite(Ign2Pin, HIGH);            // bitSet(PORTB, 3); (Turn on coil 2 charging immediately.)
    dwelltime = crankingDwelltime;          //Setting the dwelltime for cranking.
    IgnSystem = 2;                          // Statusword to know witch system is to be hot.
  }
  if ((rpm >= 300) & (IgnSystem == 2) ) {  // When running (not starting), the coil nr 1 will charge after cranktime in the ISR below.
    dwelltime = runningDwelltime;          //setting the dwelltime for running  
    IgnSystem = 1;                         //Statusword to know witch system is to be hot.
  }
  TCCR2B |= (1 << CS22);                   // Load 64 prescaler / And this starts the timer2!

  /********* RPM calculations: **********/
  half_revolutions++;                     
  if (half_revolutions >= 2) {
    rpm = 60 * 1000000 / (micros() - timeold) * half_revolutions;
    timeold = micros();
    half_revolutions = 0;
  }
}
/*========================================================================
 The interrupt action for magnet 2: The Timer starts to count up 32uS at a time.
********************************/
void SensorOff () {

  if ((rpm < 300) & (IgnSystem == 0))  {    // When cranking (starting), the coil nr 1 will charge at once.
    digitalWrite(Ign1Pin, HIGH);            // bitSet(PORTB, 0); (Turn on coil 1 charging immediately,)
   dwelltime = crankingDwelltime;           //setting the dwelltime for cranking  
    IgnSystem = 1;                          //Statusword to know witch system is to be hot.
    }
  if ((rpm >= 300) & (IgnSystem == 1) ) {   // When running (not starting), the coil nr 2 will charge after cranktime in the ISR below.
     dwelltime = runningDwelltime;          //setting the dwelltime for running   
    IgnSystem = 2;                          //Statusword to know witch system is to be hot.
  }
  TCCR2B |= (1 << CS22);                    // Load 64 prescaler / And this starts the timer2!
  
/********* RPM calculations: **********/
  half_revolutions++;       
  if (half_revolutions >= 2) {
    rpm = 60 * 1000000 / (micros() - timeold) * half_revolutions;
    timeold = micros();
    half_revolutions = 0;
  }
}
/*=============================================================================
 The Interrupt Service Routine for Timer2 that will be executed each time the timer reach the compare match register (1ms).
*****************Milliseconds****************/

ISR(TIMER2_COMPA_vect) {

  /*********Counting microseconds*****************/
  microseconds = microseconds + 32;  // Increases the variable "microseconds" by 32 every time the ISR is executed).

  /************ coil charging*****************************/
  if (microseconds >= cranktime) {  //When the microseconds reaches the cranktime, then do this:

    if (IgnSystem == 1) {   //If ignitionsystem 1 is selected and not on, then:
       digitalWrite(Ign1Pin, HIGH);  //bitSet(PORTB, 0);  (Turn on coil 1 charging.)
    } if (IgnSystem == 2) { // -"-
        digitalWrite(Ign2Pin, HIGH);  //bitSet(PORTB, 3); (Coil 2 charging.)
    }
  }
  /***********Discharge coilspark*******************************************/
  //When the microseconds has reached the cranktime and dwelltime, then:
  if (microseconds >= (cranktime + dwellTime)) {
    microseconds = 0;           // reset the uS counter variable
    //Turn off timer.
    TCCR2B  &= ~ (1 << CS22);   //clear the prescaler .
    TCNT2 = 0;                  // Reset the timer count to 0

    digitalWrite(Ign1Pin, LOW);  //bitClear(PORTB, 0); ( Stop charging coil 1. (Gives spark))
    digitalWrite(Ign2Pin, LOW);  //bitClear(PORTB, 3); (-"-)
    }
    
    // If the engine has stopped or are still cranking, the IgnSystem is set to starting advance degrees.
    if (rpm < 300) {
      IgnSystem = 0;
    }
  }

/***********************************************************/
void loop() {

  //Calculate the cranktime dependent on the rpm. (cranktime= advance time - dwellTime)
  /********************Cranktime calculations ************
       RPM  Advance        Degrees             Cranktime     Time change
            -degrees BTDC  from Sensor           (uS)        for each RPM (uS)
       300    -3            180                100000           -100000
       400     9            171                71250            -288
       600     8            172                47778            -117
       1000    7            173                28833            -47
       1700    17           163                15980            -18
       2800    26           154                9167             -6
       3100    28           152                8172             -3
       4000    29           151                6292             -2
       
  */
  if (rpm <= 300) {
    cranktime = 0;
  } if ((rpm > 300) && (rpm <= 400)) {
    cranktime = (186400 - (rpm * 288)) - dwellTime;  // = (cranktime - (rpm - 300) * Time change for each RPM) - dwellTime;
  } if ((rpm > 400) && (rpm <= 600)) {
     cranktime = (118050 - (rpm * 117)) - dwellTime; // = (71250 - (rpm - 400) * 117) - dwellTime;
  } if ((rpm > 600) && (rpm <= 1000)) {
    cranktime = (75978 - (rpm * 47)) - dwellTime;  
  } if ((rpm > 1000) && (rpm <= 1700)) {
    cranktime = (46833 - (rpm * 18)) - dwellTime;
  } if ((rpm > 1700) && (rpm <= 2800)) {
    cranktime = (26180 - (rpm * 6)) - dwellTime;
  } if ((rpm > 2800) && (rpm <= 3100)) {
    cranktime = (10007 - (rpm * 3)) - dwellTime;
  } if ((rpm > 3100) && (rpm <= 4000)) {
    cranktime = (8732 - (rpm * 2)) - dwellTime;
  }
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Senast redigerad av Stenhammar 19 januari 2016, 20:20:26, redigerad totalt 1 gång.
daer
Inlägg: 317
Blev medlem: 13 juni 2008, 22:15:27
Ort: Höör och Helsingborg, Skåne

Re: Elektroniskt tändsystem med Arduino

Inlägg av daer »

Är det något fel på detta projekt?
https://github.com/noisymime/speeduino

Kan förstå att man vill utveckla helt själv bara för se om man kan.
Fast ibland kan det vara enklare att utgå från något befintligt för att inte behöva göra allt.
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Det är från Speeduino jag har fått inspiration. Jag har faktiskt fått lite hjälp fram grundaren av Speeduino. Men det är för avancerat för min del. Jag gör hellre projekt jag kan hantera. Mitt system är tänkt för den oinvigde att ta del av. Jag började programmera för ett år sedan och detta här en del av mitt lärande.
Hoppas någon vill hjälpa mig med detta.
MiaM
Inlägg: 7347
Blev medlem: 6 maj 2009, 22:19:19

Re: Elektroniskt tändsystem med Arduino

Inlägg av MiaM »

Vilken typ av givare kommer du att använda?

En av de största poängerna med att slippa brytarspetsar är väl att slippa mekaniken som påverkar tändläget beroende på varvtal o.s.v.?
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Givarna består av en latchande hall sensor (togglande) och två neodynmagneter som är fastsatta på svänghjulet vid 3° efter övre dödläge 180° i från varandra. Den ena magneten har nordsidan pekande frammåt och den andra har sydsidan frammåt. Hall sensorn slår till när nordsidan närmar sig och är till ända tills den utsätts för en sydsida. Mitt program tar in flanksignalerna och vet då i vilket läge vevaxeln är i.
Mer information finns här:https://forum.arduino.cc/index.php?topic=369684.0
Läs första inlägget där jag har bifogat ett utkast för en system beskrivning.
You tube videon visar ju även hur magneterna fungerar. De är tejpade på den lilla propellern. Hall sensorn är bara 5 mm stor så den syns nog inte i videon.
Jag ska bifoga system beskrivningen här med när jag får tillgång till en PC.
M_Sander
Inlägg: 5
Blev medlem: 23 maj 2011, 13:56:11

Re: Elektroniskt tändsystem med Arduino

Inlägg av M_Sander »

Ja du Stenhammar, har pillat ihop nåt liknande för tvåtakts motorer. Fungerar hyfsat men du måste tänka på att det är brutala störningar via tändstiftet. Enheten måste vara totalt EMC tät.
Har en färdig kod med supermånga kommentarer i för jag glömmer alltid bort vad jag har gjort i koden, så det är lätt att härleda alla rader. Använder en Excel fil för att räkna ut tändkurvan, sedan stoppar man in den tändkurva in i koden som en tabell. Via binary search så plockar man ut advance vid X rpm... RPM räknas ut på föregående varvtal, så man ligger alltid en back, alltså endast en hall switch.
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Hej M_Sander! Kul att höra. Ja jag har märkt av störningarna, jag ska bygga en plåtlåda och skaffa skärmad kablar. Jag antar att alla motorstyrningar har samma problem.jag tittar väldigt gärna på din kod, den kan hjälpa mig att komma på nya lösningar. Jag använder oxå excel för att räkna ut tändkurvan, men har inget smidigt sätt att ändra den i koden.
Lägg gärna upp din kod här.
Tack för hjälpen!
Användarvisningsbild
hubben
Inlägg: 1754
Blev medlem: 7 september 2010, 11:46:58
Ort: Örviken

Re: Elektroniskt tändsystem med Arduino

Inlägg av hubben »

Jätteintressant projekt! Håller på att bygga en skoter till ungarna och har en 2cyl 2-taktare som har brytare idag.. Tänkte bygga brytarlöst på denna för att kunna varvtalsreglera den beroende på lite olika inparametrar, så detta projekt är jätteintressant!
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Hej Hubben! Kul! Då kan du ju använda dig av mitt system med en wasted spark tändspole med inbyggd logik. Den tänder båda tändstiften samtidigt, men det ena tändstiftet gnistrar när den ena kolven är i insugsfasen så den gnistan gör ingen skada.
Jag äger ett UL-flygplan med en Rotax582 2-taktare som har ett CDI ducati tändssystem som funkar bra, men det är ju svindyrt och inte alls lika kul för dig ;-)
Användarvisningsbild
hubben
Inlägg: 1754
Blev medlem: 7 september 2010, 11:46:58
Ort: Örviken

Re: Elektroniskt tändsystem med Arduino

Inlägg av hubben »

Exakt!
Motorn i fråga är en gammal Sachs - om jag inte missminner mig - på hela 329cc. :)
Håller på att bygga ett chassie just nu, men snart ska jag börja slita i motorn och det vore helt super med elektronisk tändning. Saken är att man vill att motorn ska varva ut fullt när skotern går tungt, är fastkörd eller kör i djupt puder.. men på hårt före vill man begränsa hastigheten så att ungarna inte blåser iväg i 90 knyck..

Så att koppla ett sånthär system och kombinera det med en sensor på sekundärvariatorn gör ju att man kan varvtalsreglera motorn med avseende på maskinens hastighet istället för att begränsa maxvarvet - vilket vore toppen!

Har en projektblogg för bygget här om det är intressant:
http://www.runstenracing.se/?cat=60
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4461
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Elektroniskt tändsystem med Arduino

Inlägg av Swech »

Kod: Markera allt

bitClear(PORTB, 3); 
Undvik att skriva rena nummer, 3 i ditt fall.
Skapa konstanter
ignition1 = 0
ignition2 = 3

så använder du dessa istället och så blir programmet mycket mer lättläst och lättare att ändra

Swech
M_Sander
Inlägg: 5
Blev medlem: 23 maj 2011, 13:56:11

Re: Elektroniskt tändsystem med Arduino

Inlägg av M_Sander »

Huva, känns lite lätt nervig att dela ut min kod till alla, ja är ingen programmerare. Detta är första gången jag delar med mig. :vissla:
Hursomhelst, det ligger en hel del arbete runt detta jobb. Läs info filen i koden o använd Excel för att tanka in tändkurvan.
Du kan ta bort allt junk som jag lagt in med display o temp o sånt.

Sedan tycker absolut att du skall skrota din propeller med el-motor. Köp en Arduino till och gör en testkod för att simulera din motor, annars kommer du aldrig rätt.
Koppla ihop dina Arduinosar med varandra. Oftast missar man att ha koll på sina input parametrar och du kommer spendera oändligt mycket tid att feppla med en motor ist för att ligga rätt i början. Jag har slängt in några Two-Stroke Simulatorer kommer inte ihåg hur dom fungerar eller vad jag tänkte just den gången.

Denna CDI eller vad man nu skall kalla den fungerar, har kört med detta på min hoj sen 2014, det var lite problem i början och dom var EMC relaterade
Tips är Optokopplare, Metall låda, skärmad kabel, ingjutning med epoxy (mycket vibrationer), bra kvalitet på kontakt don, separat/filtrerad matningsspänning för din arduino. och en riktigt bra unpolär hallswitch. Daz Arduino Pro Mini är liten o fin att använda som enhet om du blir klar lätta att gjuta in.

Idag hade jag aldrig gjort detta, det var mer eller mindre ett test som jag snöade in på, lite som gå över ån för att hämta vatten. Vet inte om detta hjälper dig med det du skall göra, men eftersom du skall ersätta brytarspetsar med en CDI antar jag att det är iallafall en början till något.

Just det om man nu hittar något i koden som är tveksamt så vill jag veta OK! :tumupp:
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

hubben skrev: Har en projektblogg för bygget här om det är intressant:
http://www.runstenracing.se/?cat=60
Mycket intressant läsning hubben! Hoppas du får användning av våra hemmagjorda program.
Swech skrev:Undvik att skriva rena nummer, 3 i ditt fall.
Skapa konstanter
Det ska jag försöka göra, kan jag alltså ersätta trean med "ign2Pin" eftersom jag har skrivit "const int Ign2Pin = 11; // (PORTB,3)" i början?
Jag kan ju även skriva digitalWrite(Ign2Pin, HIGH);
Jag fick för mig att jag skulle spara någon microsecund på att i stället skriva " bitSet(PORTB, 3);" , men det kanske är försumbart eller?
M_Sander skrev:Huva, känns lite lätt nervig att dela ut min kod till alla, ja är ingen programmerare. Detta är första gången jag delar med mig.
Men så ska du inte känna! Jag är heller ingen programmerare, ÄN! De flesta brukar ju använda forum för att lära oss nya saker, och lära ut till andra, jag hatar prestige!
Jag får tacka dig så hemskt mycket för ditt fina program! Det finns verkligen dubbelt så många sätt som det finns programmerare! Det är väldigt svårt för mig att sätta mig in i ditt program eftersom du använder dig att saker jag inte hasr hört om innan. Men, jag gör som de flesta, tar lite här och där. Jag blev överlycklig över ditt excel ark, det är precis det jag har letat efter.
Jag ska fixa en testkod till min andra arduino som du säger, men nu vet jag i alla fall hur det ska kopplas. Men jag vet inte hur jag ska kunna verifiera att tändläget hamnar rätt. Jag föreställer mig att jag gör som förr i tiden, med strobelight... men det måste ju finnas något enkelt och smidigt sätt med oscilloscope och testkoder.

Jag har med funderat på optokoplare. Men ar du att den ska kopplas mellan tändspolen och arduinon? Hinner den med då? Hur driftsäkert är det? Kan man använda parallelkopplade optokoplare som redundans?
Vilken riktigt bra unpolär hallswitch rekomenderar du då? Jag har använt denna: http://www.electrokit.com/ats177-sip3-h ... atch.48516 som jag tänkte gjuta in i ett alu rör.
Tack för tipset med Pro Mini! Jag har aldrig gjutit in någon elektronik förr, är det något särskilt att tänka på?

Jag tänkte om det skulle gå att använda en tredje arduino som ett oscilloskop med USB till PC, som den här: http://www.instructables.com/id/Arduino ... illoscope/
Då kan jag ta in signalerna från hallsensorn och från arduinons utpinnar som går till tändspolen och mäta om tiderna stämmer. Vad tycker ni om det? Eller ska jag satsa på ett riktigt skåp?
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Ny uppdaterad kod ligger i första inlägget. Har bla. använt mig av digitalWrite för tydlighetens skull.

Nu ska jag försöka mig på att göra ett oscilloskop och motorsimulator.
Stenhammar
Inlägg: 21
Blev medlem: 9 april 2015, 20:18:25

Re: Elektroniskt tändsystem med Arduino

Inlägg av Stenhammar »

Fixade en ny tändkurva i excel. Jag har bara kopierat en befintlig en. Men nu blir det enklare att förändra den i alla fall.
Jag vet inte hur många punkter jag ska ha med i koden, det beror ju på hur fin kurva man vill ha, det får bli senare bekymmer när man börjar testa.
Se bifogat.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar