Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 23:48 23 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Maximite Tacho with LCD

Author Message
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 12:48am 04 Sep 2011
Copy link to clipboard 
Print this post

I put together a little tacho program and circuit for the Maximte yesterday.

I needed to quickly measure the RPM of a alternator I was testing ( http://www.thebackshed.com/forum/forum_posts.asp?TID=3504&PN =1&TPN=11 ) and my usual tools were letting me down.



I do have a Oatley Electronics K117 opto-tacho kit, but it needed calibration and was very slow to respond, I no longer have a copy of the instructions, plus Oatley dont have them on their web site either unfortunately. But the K117's optic circuit was working, and it flashed a LED for each revolution of the alternator.

So I connected the LED to a opto coupler, feeding pin 18 of the Maximite. On pin 17 I conneced a LED, to flash with each revolution, and on pins 11 to 16 is a LCD module. This circuit is copied from the LCD.pdf file, with a few additions on pin 17 and 18.



The LCD module displays the cycle time in ms, the duty cycle ( LED off in this case ), the frequency in Hz and the RPM.



Here's to code. Its mostly the LCD routine included with the Maximite samples, with the tacho routines from 100 to 400.


100 SETPIN 17,8
110 SETPIN 18,2
120 PIN(17)=0
130 GOSUB 11000 ' Initialise the LCD
140 LCD_line1$ = "Waiting for "
150 LCD_line2$ = "Signal "
160 GOSUB 12000
170 '
180 ' Main Loop
190 '
200 PIN(17)=1
210 DO WHILE PIN(18)=1
220 LOOP
230 StartTime=TIMER
240 DO WHILE PIN(18)=0
250 LOOP
260 MidTime=TIMER
270 PIN(17)=0
280 DO WHILE PIN(18)=1
290 LOOP
300 TotalTime=TIMER-StartTime
310 IF TotalTime>0 THEN
320 DutyCycle=100/TotalTime*(MidTime-StartTime)
330 LCD_line1$=STR$(INT(TotalTime)) + "ms " + STR$(INT(DutyCycle)) + "% Duty "
340 TotalTime=TotalTime/1000
350 Hz=1/TotalTime
360 RPM=Hz*60
370 LCD_line2$=FORMAT$(Hz,"%.1f") + "Hz " + FORMAT$(RPM,"%.1f") + "RPM "
380 ENDIF
390 GOSUB 12000
400 GOTO 200
11000 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''
11010 ' Initialise the LCD
11020 '
11030 FOR i = 11 TO 16 : SETPIN i, 9 : NEXT i
11040 _LCD_byte = &B0011 : GOSUB 13090 : PAUSE 5 ' reset
11050 _LCD_byte = &B0011 : GOSUB 13090 : PAUSE 5 ' reset
11060 _LCD_byte = &B0011 : GOSUB 13090 : PAUSE 5 ' reset
11070 _LCD_byte = &B0010 : GOSUB 13090 : PAUSE 2 ' 4 bit mode
11080 _LCD_byte = &B00101100 : GOSUB 13000 ' 4 bit, 2 lines
11090 _LCD_byte = &B00001100 : GOSUB 13000 ' display on, no cursor
11100 _LCD_byte = &B00000110 : GOSUB 13000 ' increment on write
11110 _LCD_byte = &B00000001 : GOSUB 13000 ' clear display
11115 PAUSE 2
11120 RETURN
12000 ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''
12010 ' send the two lines to the LCD
12030 '
12040 _LCD_byte = &H80 : GOSUB 13000 ' select the 1st line
12050 FOR _LCD = 1 TO 16
12060 _LCD_byte = ASC(MID$(LCD_Line1$, _LCD, 1))
12070 PIN(11) = 1 : GOSUB 13000 ' send the character
12080 NEXT _LCD
12090 _LCD_byte = &B11000000 : GOSUB 13000 ' select the 2nd line
12100 FOR _LCD = 1 TO 16
12110 _LCD_byte = ASC(MID$(LCD_Line2$, _LCD, 1))
12120 PIN(11) = 1 : GOSUB 13000 ' send the character
12130 NEXT _LCD
12140 RETURN
13000 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''
13010 ' Send a byte to the LCD
13020 ' the data to be sent is in _LCD_byte
13030 '
13040 PIN(13) = _LCD_byte AND &B00010000 ' output the 1st 4 bits
13050 PIN(14) = _LCD_byte AND &B00100000
13060 PIN(15) = _LCD_byte AND &B01000000
13070 PIN(16) = _LCD_byte AND &B10000000
13080 PIN(12) = 1 : PIN(12) = 0 ' tell lcd to accept data
13090 ' Entry point to send just 4 bits to the LCD
13100 PIN(13) = _LCD_byte AND &B00000001 ' output the 2nd 4 bits
13110 PIN(14) = _LCD_byte AND &B00000010
13120 PIN(15) = _LCD_byte AND &B00000100
13130 PIN(16) = _LCD_byte AND &B00001000
13140 PIN(12) = 1 : PIN(12) = 0 : PIN(11) = 0 ' tell lcd to accept data
13150 RETURN


Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
Ray B
Senior Member

Joined: 16/02/2007
Location: Australia
Posts: 219
Posted: 01:59am 04 Sep 2011
Copy link to clipboard 
Print this post

Excellent example of what can be achieved with a MM and something well documented from which others can learn. We need more of what has been achieved.
RayB from Perth WA
 
crackerjack

Senior Member

Joined: 11/07/2011
Location: Australia
Posts: 164
Posted: 07:16am 04 Sep 2011
Copy link to clipboard 
Print this post

Excellent - this is what the Maximite is all about: rapid turnaround from idea to implementation. Gizmo's post is in the great spirit of this Forum in sharing code, ideas and circuits - thanks for this and for hosting this forum of opportunities to share and learn.
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 11:42am 04 Sep 2011
Copy link to clipboard 
Print this post

Thanks guys. I do see the Maximite as a tool more than a computer, and its perfect for little applications like this, lots of I/O pins and easy to program.

There is a little timing problem I'll look at tomorrow. It reads fast. At 1.6Hz it reads 1.8Hz, and it gets worse as the frequency goes up, at 8.7Hz its reading 15.6Hz. Maybe a timing issue in the Maximite, though the DO WHILE PIN() loops are not the best way to do this sort of thing. I might look at using the interupts instead.

Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 01:05pm 04 Sep 2011
Copy link to clipboard 
Print this post

Hi Glenn.

Yes, you will definitely have to move to using the interrupts.

In the current code, the StartTime variable is being set after the LCD update routines. The LCD update routine (and associated calculations) will take a relatively constant time. The faster the pulses arrive, the later in the cycle the StartTime value is set - therefore giving a "shorter" TotalTime. Hence the frequency increases....

Regards

Gerard (vk3cg/vk3grs)
 
Talbit
Senior Member

Joined: 07/06/2011
Location: Australia
Posts: 210
Posted: 01:55pm 04 Sep 2011
Copy link to clipboard 
Print this post

Gizmo,
How does your LCD circuit work, because it's wired up incorrectly? See Geoffs' latest circuit. He has corrected his mistake.
Talbit
Talbit
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 10:14pm 04 Sep 2011
Copy link to clipboard 
Print this post

Ah, yes, your right, I just grabed the circuit from the original PDF, but as you said its wrong. My LCD is wired up correctly. I'll update that imaage later.

Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 10:29pm 04 Sep 2011
Copy link to clipboard 
Print this post

i`m waiting on some new code from gerard for my inverter.. as i do have it running if only to generate a square wave or pulse width -mod ... how ever you see it...
and also to have the few results i have on screen in the program like adj`s freq and m`s`ratio and main battery voltage going to try and mod the code my self soon ..as i am not very good with code ..i`m more of an anolouge tech`y really .. going to get a small screen prolly one of those seven inch lcd`s ...
to me its all about current .....interesting stuff there gizzmo
technicians do it with least resistance
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 11:36pm 04 Sep 2011
Copy link to clipboard 
Print this post

The circuit diagram is correct now.

Looking into using the interupts, but I have a question. What if a interupt routine is running, and its triggered again before its finished ( ireturn )? Will it restart, or will we have two routines, which could be dangerous for RAM?

Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 11:51pm 04 Sep 2011
Copy link to clipboard 
Print this post

  Gizmo said  Looking into using the interupts, but I have a question. What if a interupt routine is running, and its triggered again before its finished ( ireturn )? Will it restart, or will we have two routines, which could be dangerous for RAM?

Glenn


Hi Glenn.

When a MMBasic interrupt routine is executing, no other MMBasic interrupt routine will be executed until the currently running routine has completed (ie the IRETURN statement is executed).

At that point the interrupt check routine will run and if there is a matching condition to trigger a MMBasic interrupt routine it will be invoked. All interrupts in MMBasic have a relative priority and the interrupt check routine always starts its check with the highest priority interrupt.

Regards

Gerard (vk3cg/vk3grs)
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 12:03am 05 Sep 2011
Copy link to clipboard 
Print this post

sorry excuse me to interupt ...

i have been playing round with my inverter program and starting to "setpin" for the extra voltges that i want to measure ...getting there regards sparkey ...
technicians do it with least resistance
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 12:09am 05 Sep 2011
Copy link to clipboard 
Print this post

Thanks for clearing that up Gerard.

I have another question, more of a "Best Practices", thats applicable to this project. If my program revolves around one interupt, and its always waiting for this interupt to do its "thing", then what should it be going in the mean time? eg..


10 SETPIN 18,6,100 ' the interupt
20 goto 20

100 ' Do stuff
110 ireturn


Line 20, where the Maximite is just waiting. Is there a best programming practice for a loop thats does nothing other than loop.

Glenn
The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 12:24am 05 Sep 2011
Copy link to clipboard 
Print this post

Hi Glenn.

The following is just my opinion, and there may be other ways to do it as well.

I would have your interrupt routine doing the absolute minimum amount of processing possible. In this case it would be to store the current timer value and then set a flag/state variable that the main program will interrogate.

The main program would loop checking the flag/state variable. When the appropriate "state" is set it would then perform its calculations and update the LCD display. As you are interested in the time of both the low-to-high and high-to-low transistions, it may be applicable to tie two input pins together and have one set to interrupt on low-high and the other set to interrupt on high-low. The 2 interrupt routines would set their timer variables and the main program would perform the work as above.


Regards

Gerard (vk3cg/vk3grs)
 
Gizmo

Admin Group

Joined: 05/06/2004
Location: Australia
Posts: 5078
Posted: 12:48am 05 Sep 2011
Copy link to clipboard 
Print this post

Thanks Gerard

I'll look into that, would be more efficient.

This code works accurately, but not the best solution. It updates the LCD on every 2nd revolution.


100 SETPIN 17,8
110 SETPIN 18,6,500
120 PIN(17)=0
130 GOSUB 11000 ' Initialise the LCD
140 LCD_line1$ = "Waiting for "
150 LCD_line2$ = "Signal "
160 GOSUB 12000
170 '
180 ' Do nothing loop
190 '
200 goto 200
490 '
500 ' Timing routine
501 '
510 TIMER=0
515 PIN(17)=1
520 DO WHILE PIN(18)=1
530 LOOP
540 MidTime=TIMER
550 PIN(17)=0
560 DO WHILE PIN(18)=0
570 LOOP
580 TotalTime=TIMER
590 IF TotalTime>0 THEN
600 DutyCycle=100/TotalTime*MidTime
605 LCD_line1$=STR$(INT(TotalTime))+"ms "+STR$(INT(DutyCycle))+"% Duty "
610 TotalTime=TotalTime/1000
620 Hz=1/TotalTime
630 RPM=Hz*60
640 LCD_line2$=FORMAT$(Hz,"%.1f") + "Hz " + FORMAT$(RPM,"%.1f") + "RPM "
645 gosub 12000
650 ENDIF
660 Pause 1 ' to make sure the pulse has passed
670 ireturn

LCD routines not shown



Glenn

The best time to plant a tree was twenty years ago, the second best time is right now.
JAQ
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024