RTCC with SX/B help request on magneto/throttle project
Ken Gracey
Posts: 7,419
Hey SXers:
This is my first time attempting to use the SX's RTCC ISR. This portion of the·project consists of a Honda engine magneto connected to an SX, with a servo for throttle control. The goal is to control the throttle using a known RPM. The bigger project is that I've got an alternator connected to the engine for a high-powered robot power plant for over-the-snow travel. But·this is where I'm stuck.·The signals I'm dealing with look like this (servo on top, magneto on bottom):

Every 20-50 ms I generate·the servo pulse, and meanwhile I'd like to be counting magneto pulses for 1 second. The scope capture above shows the engine in an idle state, so the pulse frequency increases with RPM. I'm able to control the servo and count pulses accurately, but putting these two tasks together is where I need some help. You can ignore the R/C circuit with the potentiometer - the purpose of that was to manually set the throttle so I could test the pieces of this project before I tried to put it all together.
This is my schematic:

I created some psuedo-code which compiles, though·the use of PULSOUT in the interrupt routine·will wreck the timing. How can I incorporate the adjustment of a servo timing pulse·within the ISR?·It seems like I'd use the tix counter to adjust servo pulses.·Do I need to·make a relationship between ServoVal and tix variables, so that I use tix and HIGH/LOW Servo·in the ISR to control the servo? I·would benefit from a couple more hints.·Preliminary·psuedo-code is below, so you·can understand the·approach I'm trying to take.
'
' Throttle Feedback Control.SXB
' Magneto counting for Honda Engine / alternator coupling
' to set an RPM between two values
'
DEVICE········· SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ··········· 4_000_000
'
' I/O Pins
'
Servo·········· PIN·RA.1· OUTPUT
Magneto········ PIN·RB.4· INPUT CMOS
RCCircuit······ PIN·RC.3· INPUT· ' not used in this code·
'
' Constants
'
HighThrottle··· CON·130
LowThrottle···· CON·190
'
' Variables
'
ServoVal······· VAR·Word
analog········· VAR·Word
RPM············ VAR·Word
MagnetoPulses·· VAR·Byte
tix············ VAR·Byte
'
· INTERRUPT 200
'
ISR_Start:
· INC tix······································ ' update tix counter
· IF tix = 10 THEN····························· ' every 50 ms
··· tix = 0
··· PULSOUT Servo, ServoVal
· ENDIF
ISR_Exit:
· RETURNINT·
' =========================================================================
· PROGRAM Start
' =========================================================================
Start:
· ServoVal = LowThrottle
CountRPMs:
· COUNT Magneto, 1000, MagnetoPulses
· RPM = MagnetoPulses * 60
· IF RPM <· 3000 THEN
··· ServoVal = ServoVal - 5 ················· ' increase throttle
··· IF RPM > 4000 THEN
··· ServoVal = ServoVal······················ ' hold throttle
····· IF RPM > 5000 THEN
····· ServoVal = ServoVal + 5················ ' decrease throttle
····· ENDIF
··· ENDIF
· ENDIF
GOTO CountRPMs
Thanks for any help ahead of time.·
Ken Gracey
Parallax, Inc. ·
Post Edited (Ken Gracey (Parallax)) : 10/6/2006 6:09:22 PM GMT
This is my first time attempting to use the SX's RTCC ISR. This portion of the·project consists of a Honda engine magneto connected to an SX, with a servo for throttle control. The goal is to control the throttle using a known RPM. The bigger project is that I've got an alternator connected to the engine for a high-powered robot power plant for over-the-snow travel. But·this is where I'm stuck.·The signals I'm dealing with look like this (servo on top, magneto on bottom):
Every 20-50 ms I generate·the servo pulse, and meanwhile I'd like to be counting magneto pulses for 1 second. The scope capture above shows the engine in an idle state, so the pulse frequency increases with RPM. I'm able to control the servo and count pulses accurately, but putting these two tasks together is where I need some help. You can ignore the R/C circuit with the potentiometer - the purpose of that was to manually set the throttle so I could test the pieces of this project before I tried to put it all together.
This is my schematic:
I created some psuedo-code which compiles, though·the use of PULSOUT in the interrupt routine·will wreck the timing. How can I incorporate the adjustment of a servo timing pulse·within the ISR?·It seems like I'd use the tix counter to adjust servo pulses.·Do I need to·make a relationship between ServoVal and tix variables, so that I use tix and HIGH/LOW Servo·in the ISR to control the servo? I·would benefit from a couple more hints.·Preliminary·psuedo-code is below, so you·can understand the·approach I'm trying to take.
'
' Throttle Feedback Control.SXB
' Magneto counting for Honda Engine / alternator coupling
' to set an RPM between two values
'
DEVICE········· SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ··········· 4_000_000
'
' I/O Pins
'
Servo·········· PIN·RA.1· OUTPUT
Magneto········ PIN·RB.4· INPUT CMOS
RCCircuit······ PIN·RC.3· INPUT· ' not used in this code·
'
' Constants
'
HighThrottle··· CON·130
LowThrottle···· CON·190
'
' Variables
'
ServoVal······· VAR·Word
analog········· VAR·Word
RPM············ VAR·Word
MagnetoPulses·· VAR·Byte
tix············ VAR·Byte
'
· INTERRUPT 200
'
ISR_Start:
· INC tix······································ ' update tix counter
· IF tix = 10 THEN····························· ' every 50 ms
··· tix = 0
··· PULSOUT Servo, ServoVal
· ENDIF
ISR_Exit:
· RETURNINT·
' =========================================================================
· PROGRAM Start
' =========================================================================
Start:
· ServoVal = LowThrottle
CountRPMs:
· COUNT Magneto, 1000, MagnetoPulses
· RPM = MagnetoPulses * 60
· IF RPM <· 3000 THEN
··· ServoVal = ServoVal - 5 ················· ' increase throttle
··· IF RPM > 4000 THEN
··· ServoVal = ServoVal······················ ' hold throttle
····· IF RPM > 5000 THEN
····· ServoVal = ServoVal + 5················ ' decrease throttle
····· ENDIF
··· ENDIF
· ENDIF
GOTO CountRPMs
Thanks for any help ahead of time.·
Ken Gracey
Parallax, Inc. ·
Post Edited (Ken Gracey (Parallax)) : 10/6/2006 6:09:22 PM GMT




Comments
How fast can the magneto pulses be at maximum RPM ?
P.S. I hate to bring this up, but the SX48 could handle both of these functions using JUST the two hardware timers.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·
The fastest magneto pulses I'm counting are 200 per second, and best I can tell I get two pulses per rotation. 200 x 60 / 2 = 6,000 rpm. Idle is around 50 pulses per second.
I forgot to say why I want RPM control. I've got a voltage regulator circuit which generates a known amount of current at different RPMs. I could come close to achieving what I want with an open-loop throttle, but since I've come this far. . .
I could use the SX48 Proto Board - not a problem especially if it makes the coding more practical. Sure.
Ken Gracey
Parallax, Inc.
Post Edited (Ken Gracey (Parallax)) : 10/6/2006 7:33:23 PM GMT
However, the COUNT function will not be precise for two reasons:
1) Time spent in the ISR does not count against your 1000 msecs timing interval. In your case the ISR time will vary with the width of the servo pulse. Worst case, on average around 4% of your time will be in the ISR, so this probably isn't a concern here.
2) If a magneto pulse happens during a servo pulse, it won't get counted. The COUNT function can't register a pulse unless it (and not the ISR) is running when the pulse happens. Since the magneto pulses can be shorter than the servo pulses, this is a definite possibility. Again, you may be able to convince yourself that missing a few pulses won't be a problem for this project.
If you decide you need to, you can solve both of these problems by coding the pulse counter yourself. You could add code to the ISR to set a bit flag once per second (every 200 executions of the ISR). WKPND_B.4 will be set every time there is a magneto pulse, independent of what code is running. You just have to clear it before the next pulse comes along. Create a loop that checks and clears WPKND_B.4, increments the count when it's set, and loops until the 1 second flag is set. When that happens, clear the 1 second flag and save the count.
There's a trick to using the WKPND_B register. WKPND_B = ByteVar will actually swap the value of ByteVar and the value of WKPND_B. So the the pulse counting code would be:
CountRPMS:
MagnetoPulses = 0
DO
Temp = 0
WKPND_B = Temp 'Temp gets the value of WKPND_B and WKPND_B is cleared and ready for the next pulse
IF Temp.4 = 1 THEN
INC MagnetoPulses
ENDIF
LOOP UNTIL OneSecondFlag = 1
OneSecondFlag = 0
'Update ServoVal here
GOTO CountRPMS
By the way, you'll probably want to force ServoVal to stay between LowThrottle and HighThrottle.
CountRPMS:
·· MagnetoPulses = 0
·· DO
····· Temp = 0
····· WKPND_B = Temp 'Temp gets the value of WKPND_B and WKPND_B is cleared and ready for the next pulse
····· IF Temp.4 = 1 THEN
········ INC MagnetoPulses
····· ENDIF
·· LOOP UNTIL OneSecondFlag = 1
·· OneSecondFlag = 0
·· 'Update ServoVal here
GOTO CountRPMS
· I would use RTCC to count the mag pulses. And update the servo in the program loop.
· This will work on the SX28 or SX48. And no messy interrupts are needed.
· Something like: [noparse][[/noparse]WARNING...UNTESTED CODE AHEAD!]
OPTION = %11111111 ' Setup RTCC inc from external pin (Mag pulse) servoPos = 150 ' 1.5 milliseconds DO RTCC = 0 FOR cnt=1 TO 50 servoPin = 1 PAUSEUS servoPos * 10 servoPin = 0 servoPos = 255 - servoPos PAUSEUS servoPos * 10 servoPos = 255 - servoPos ' Delayed 2.550 milliseconds so far PAUSE 17.45 ' Make total delay 20mSec NEXT magCnt = RTCC ' Do something with magCnt LOOPBean.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·
Now wait just a minute...... there is nothing "messy" about interrupts. It permits you to do things exactly and deterministically. In fact, I bellieve it to be the ONLY way to code time related programs...... I would never stoop to using a "pause" (OK, perhaps a few NOPs for a few cycles) to wait for anything. With interrupts, (simple) multi-tasking is a breeze, and pre-emptive multi-tasking is very achievable in an SX28.
That said, with the exception of the PAUSE function, I do like what you have done with SX/B. You can get a lot done with only a little effort. It appears to be well respected for non time-critical applications, and has garnered quite a following. For real-time multi threading however, something more substantial is required employing those darned "ISR's", and that's the field where I like to "mess".
Keep up the good work.
Cheers,
Peter (pjv)
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·
Interesting, your approach.
Where on the other hand, I never write a program without interrupts, even if it just returns..... it's a standard piece in my template. It becomes so second nature, and it really helps (me, at least) clarify the dissection of a software structure for any particular requirement.
Cheers,
Peter (pjv)
I agree. Time spent learning how to handle interrupts and communication between FG and BG code is time well spent. Perhaps the single strongest feature of the SX chips is the jitter free interrupt. I can treat the SX like a piece of dedicated hardware because the lack of jitter in the interrupt system allows me to have 100% deterministic response time.
In addition, by dividing tasks between FG and BG, I guarantee time critical code is executed. In one of my projects, I have an SX that communicates with a 68HC11. The SX polls the communications lines in the interrupt handler. Mind you, it doesn't block. It just checks the status and acts when the line has done what it is waiting for. By counting the duration of the code path in the 68HC11, I am able to set an RTCC interrupt rate in the SX that absolutely guarantees it will never miss a communication request by the 68HC11. There is no wondering if it's fast enough. I can prove that I am sampling the communication line at around 3X faster than the 68HC11 can toggle it. This allows my FG code to do whatever it needs with the data as it comes in because the interrupt will always catch the data and notify the FG when it is ready.
This has also given me a huge advantage in writing multi-threaded code for Windows. The lessons learned on how to synchronize communication between the FG and BG is just like synchronizing communication between threads in Windows. As a result, my multi-threaded Windows apps cruise along without running afoul of issues like race conditions because I learned how to deal with those (the hard way) writing assembly language code (using interrupts) on various micro platforms.
Thanks, PeterM
OT: Sort of
Ken,
What type of alternator are you using with the GX-35?
Is it a direct drive or are you using a pulley/chain arrangement?
Is the GX-35 electric start or pull?
Some Pics would be neat!
I've kept my daughter's motorized car she had when she was little, now 13. Was think about making a 'explorer' bot (probably just R/C for now) out of it.
Thanks,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mike
tacho pulses are kinda asynchronous. Using an ISR to catch them, means that the ISR must be executetd often enough in order not to miss anya tacho pulse transition, so the ISR would act as a "fast poller" on the tacho input line. As the SX is faster than many oher controllers, this may, or may be not a problem.
Nevertheless, please don't forget another great SX feature: The "wake-up" capability of the port B inputs. What is called the "wake-up capability" is actually a endge-capture feature available on the port B inputs. You can configure each of them to capture a rising or falling input signal edge, using the WKPED_B configuration register. You may configure the individual port B inputs to issue an interrupt, or a wake-up event using the WKEN_B configuration register. But even without enabling interrupts/wakeups on port B transitions, you can always "read" the WKPND_B register to find out if the input has changed to the configured direction since the last read. Actually, you do an exchange between W and the WKPND_B registers, so the instruction sequence
mov w, #0
mode $09
mov !rb, w
copies the current status of the wakeup pending bits into w, and clears them for the next run.
This feature is especially handy when you have to deal with very short pulses. Let's assume that the pulses look like to this:
_______________-_______________-_____________
and you poll the input at times shown here:
____|____|____|____|____|____|____|____|____|____
So, you will miss all the low-high transitions, although you are polling the input faster than the pulse period.
The status of a WKPND_B register bit would look like this (assuming that it is cleared whenever it is read):
______________
____________----____________
i.e. it goes high on a rising input signal, and low again when it is read by the SX program, so you won't miss any input transition using this feature.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
Thanks a bunch for the help. I'm going to do a bit more research on RTCC to see if it can achieve my goals. I'll put the tach pulses on the RTCC pin and deal with the servo in my main program. I need to see if this pin can be set to CMOS. This seems likea fairly light-duty approach compared to the edge detection tips from Guenther and Peter's encouragement to learn ISRs inside and out, but it's a small step in the right direction from my standpoint. I'll be working on this over the next day or two and will report back my findings.
Mike,
This is a direct coupling arrangement. I don't want to mess around with chains or pulleys due to safety, power loss, and general "junk" that I consider it in my system. Basically, this system is producing 15-20A without problem and the battery is acting like a giant capacitor in the project. This is the·power plant "test bed" I built, which·was only assembled to prove to myself that the concept is feasible. I've connected loads over 15A at 12V·and I can deliver this power for an hour and a half with this engine. I'll post the·whole entire project in·the "Projects" section of this forum once I get the SX to count magneto pulses. I'll post mechanical drawings, too.
Ken Gracey
Parallax, Inc.
I "THINK" I remember reading somewhere that the RTCC pin is schmitt trigger levels. So you may need to run the magneto pulse through a gate to "square it up" first. I'd try it straight in first.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·
·
Just for interest I thought I would code up in assembler (my skills at SX/B are inadequate) what I think you are trying to do.
·
I believe your project is well served by a simple minded co-operative scheduler and state machines, so I thought it to be a good example to demonstrate those.
·
I have not followed your port bits and numbers scaling as I was not at my internet connection at the time I coded this, so I was going by memory as to what the concepts were, and that was what I implemented.
·
Essentially my example shows several concepts, and how to execute several independently timed concurrent routines "simultaneously":
·
1. use interrupt to time all events
2. read magneto pulses for one second
3. use port B change detection as per Guenther's example above
4. output servo pulses from 1 through 2 milliseconds duration
5. calculate throttle raise/lower requirements
·
A virtual A/D converter for a pot-adjusting RPM setpoint can be readily incorporated.
·
This particular implementation is not as concise as I would normally code it, as that would obscure some of the concepts for those who are trying to learn from these examples, and this version is only one of many ways to "skin this cat".
·
It's also interesting to note the difference in effort between an SX/B (your code rendering) and assembler. It took me about 3 hours to figure out what was needed, how to tackle it, write the code starting with my standard template, and another hour to debug it and run it with simulated inputs/outputs. Then it took me another two hours to edit the post so formatting was intact·for·making it·readable !
My scope verified proper operation of the servo pulse outputs, but using the imprecise internal R/C oscillator caused a little error in the timing. During "DEBUG", while the SX key was generating the clock, timing was perfect.
·
·
Anyhow do with it what you will, and I'd be happy to add the A/D or any other features you might desire.
·
Cheers,
·
Peter (pjv)
id 'Gracey1' ; Oct8, 2006 Device SX28, Osc4MHz, Turbo, Optionx ;new assembler ; Device watchdog ;turn the watchdog on ; Device bor42 ;turn brown-out detect on ; Device carryx ;turn extended carry on ; Device protect ;turn program read protection on Freq 4_000_000 ;run speed Reset Initialize ;start at label on reset IRC_Cal IRC_Slow ;;Interrupt ============================================= org 0 ; Interrupt setb Intflag ;interrupt based tick generator mov w,#IntConst ;load interrupt interval value retiw ;Initialize ;===========================================;Program starts here on power-up and on reset. InitLevels mov m,#ModeLevel ;Set to 0 for CMOS levels mov !ra,#%0000 ; mov !rb,#%0000_0000 ; mov !rc,#%0000_0000 ; InitPullup mov m,#ModePullup ;Set to 0 for pullups mov !ra,#%0000 ; mov !rb,#%0000_0000 ; mov !rc,#%0000_0000 ; InitEdgeDetect mov m,#ModeBPend ;clear out any pending bits before enabling edge detect interrupt mov !rb,#0 ; InitTris mov m,#ModeTristate ;Set to 0 for output clr ra ; mov !ra,#%1111 ;all inputs clr rb ; mov !rb,#%1111_1111 ;all inputs clr rc ; mov !rc,#%0000_0000 ;all outputs ClrMem clr fsr ;beginning of ram ClrOne setb fsr.4 ;stay in upper half clr ind ;clear location incsz fsr ;next location jmp ClrOne ;continue clearing clr Flags ; InitTimers bank Timers ; mov w,#4 ; mov Time1,w ;100 uSec timer mov w,#10 ; mov Time2,w ; 1 mSec timer mov Time3,w ; 10 mSec timer mov Time4,w ;100 mSec timer mov Time5,w ; 1 Sec timer InitMagneto mov MagnetoState,#MagnetoIdle ;initial state for magneto routines InitServo mov ServoState,#ServoIdle ;initial state for servo routines mov ServoLoad,#ServoMin ;low setting InitRTCC clr rtcc ; mov !option,#RTCCIntEnable ;enable interrupt jmp Main ;;Mainline program loop ================================= Main sb Intflag ;wait for occurence of an interrupt jmp Main ; uSec25 clrb Intflag ;act on interrupt event ;put 25 uSec scheduled events here call Servo ;do required state of servo routines bank Timers ; decsz Time1 ; jmp Main ; uSec100 mov Time1,#4 ;reload timer for another 100 uSec (4 ticks of 25 uSec) ;put 100 uSec scheduled events here bank Timers ; decsz Time2 ; jmp Main ; mSec1 mov Time2,#10 ;reload timer for another 1 mSec ;put 1 mSec scheduled events here call Magneto ;do required state of magneto routines bank Timers ; decsz Time3 ; jmp Main ; mSec10 mov Time3,#10 ;reload timer for another 10 mSec ;put 10 mSec scheduled events here mov ServoState,#ServoStart ;trigger a servo out pulse duration sequence every 10 mSec bank Timers ; decsz Time4 ; jmp Main ; mSec100 mov Time4,#10 ;reload timer for another 100 mSec ;put 100 mSec scheduled events here bank Timers ; decsz Time5 ; jmp Main ; SecOne mov Time5,#10 ;reload timer for another 1 Sec ;put 1 Sec scheduled events here call Control ;calculate change for servo jmp Main ;MagnetoStart clr MagnetoAccumulatorLo ;zero the magneto pulse counter clr MagnetoAccumulatorHi ; mov MagnetoState,#MagnetoFall ;from now on look for a falling pulse level MagnetoFall mov m,#ModeBPend ;switch to pending mode clr w ; mov !rb,w ;read and clear any port b transition pending bits test w ;determine any changed bits on port b snz ;skip on changes jmp MagnetoExit ;no magneto pulses detected MagnetoPulse incsz MagnetoAccumulatorLo ;keep track of magneto pulse count skip ; inc MagnetoAccumulatorHi ;16 bit counter MagnetoExit mov m,#ModeTristate ;restore direction mode... not neccessarily required in this simple case retp ;ServoStart mov w,ServoLoad ;load up the servo pulse duration value; can be 1 through 255 ticks of the 10 uSec time base snz ;check for non-zero retp ;bail out for value of zero mov ServoDuration,w ;set the servo duration timer setb ServoOut ;set servo pin high mov ServoState,#ServoPulse ;next time count one tick of the servo pulse output retp ; ServoPulse decsz ServoDuration ;count ticks until counter is depleted retp ; clrb ServoOut ;servo pulse is now finished mov ServoState,#ServoIdle ;next go to idle state until we are triggered again retp ;Control mov MagnetoState,#MagnetoIdle ;stop magneto pulse accumulation rl MagnetoAccumulatorLo ;only use 13 bits of 16 bit accumulator; good up to 8191 magneto pulses in one second rl MagnetoAccumulatorHi ; rl MagnetoAccumulatorLo ;only use 13 bits of 16 bit accumulator rl MagnetoAccumulatorHi ; rl MagnetoAccumulatorLo ;only use 13 bits of 16 bit accumulator rl MagnetoAccumulatorHi ; mov MagnetoCount,MagnetoAccumulatorHi;only use most significant byte of pulse accumulation of previous one second cjb MagnetoCount,#LowSetpoint,Raise ;increase throttle if magneto is below setpoint cja MagnetoCount,#HighSetpoint,Lower;decrease throttle if magneto is above setpoint ControlExit mov MagnetoState,#MagnetoStart ;trigger a one second magneto pulse accumulation retp ;Raise add ServoLoad,#RaiseSize ;increase servo pulse duration snc ;look for roll-over jmp SetMax ; csa ServoLoad,#ServoMax ;look for overflow jmp ControlExit ; SetMax mov ServoLoad,#ServoMax ;limit to some maximum jmp ControlExit ;Lower sub ServoLoad,#LowerSize ;decrease servo pulse duration sc ;look ror roll-under jmp SetMin ; csb ServoLoad,#ServoMin ;look for underflow jmp ControlExit ; SetMin mov ServoLoad,#ServoMin ;limit to some minimum jmp ControlExit ;Post Edit:··· Well, it looks like my effort to retain the formatting is for naught! This is so difficult to read..... I really wish there was another way to make things easier.·I hope the attached copy is proper !
Post Edit: fixed missing literal indicator (#) in "MagnetoExit" line.
Cheers,
·Peter (pjv)
Post Edited (pjv) : 10/10/2006 3:39:31 PM GMT
You might want to take a look at:
http://www.piclist.com/images/boards/Injector-JAW/index.htm which does injector control for a motorcycle engine. The code is for the PIC, but it can be converted.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james at sxlist,com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
This is fantastic. I'm spending some time studying the code example before I reply in detail to make sure I've got a basic grasp of the concepts. I'll be at home on Tuesday evening, and should be able to run it as early as Wednesday morning. I truly appreciate the help and look forward to reporting back with results! Thanks again!
You guys have tons of solutions for me!
Sincerely,
Ken Gracey
Parallax, Inc.
That's a pretty sweet setup! Looks like you work in aluminum like I do in MDF. Wish my home built CNC router would cut aluminum, probably will but will have to make MANY passes, need to try one day. Hope to see this in the 'Projects' section soon, you've sparked my interest!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Mike
I spotted an error in my code; a missing literal indicator (#) in the "MagnetoExit" line. Eventhough it ran fine in my trial, it might have screwed up later if you added more features.
I have "post-fixed" this.
Cheers,
Peter (pjv)
Your power generator looks great! It is a work of art. I would enjoy reading a full article on the project.
I suspect that your battery is closer to 10 Ahr rather than the 10 mAhr noted in the schematic of the LM723 voltage regulator.
Are you planning on taking the next step and replacing the LM723 with the SX for regulation of the field current? In theory it should be rather simple.
Just keep the voltage divider read the voltage with the SX. Replace the 2N3055 with a logic level MOSFET controlled with the SX (buffer with an ICL7667 style MOSFET driver if you want very fast edges) and PWM the field coil. A loop update rate of 100Hz to 200Hz should be plenty.
In addition being cool and reducing the parts count, you would also get more run time. You would save the power lost due to the base current of the 2N3055 as well as the associated I*Vce losses. You might even be able to eliminate the 16 ohm resistor in series with the field coil for additional power savings.
You might want to throw in a one-wire temperature sensor to make sure the alternator is not getting to hot at full load.
I also wanted to throw in with Guenther. The best way to accurately count short events is to use an interrupt on level change (edge). Otherwise you are guaranteed to eventually miss events unless your time between samples is shorter than the minimum event duration.
Congratulations again on such a well designed project. I look forward to reading more about the design and build.
-Shane