Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 11:00 19 May 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 : Newbie

     Page 6 of 7    
Author Message
Bob

Regular Member

Joined: 11/08/2011
Location: United Kingdom
Posts: 41
Posted: 08:24am 26 Aug 2011
Copy link to clipboard 
Print this post

Hi Dinosaur,

  Dinosaur said   Hi all

Just as a 'hopeless suggestion' (my best sort), would it be possible to code things so that every time an IRETURN from the service routine line (in BASIC) occurs,
one (or 'n') further BASIC statement is executed before the next interrupt is honoured? That would be a possible way of ensuring that the main BASIC programme can continue to run, albeit rather crippled...

Bob, I think that would defeat the purpose of an Interupt.
Am I right in assuming that the reason this PIC is so slow in handling Int, is that we are running Interpreted Basic ? I wonder if I re-wrote it in MikroBasic if it would significantly increase the speed.

Regards
EDIT: Also the maximum rate is 1Khz.


Allowing the interpreter to run one BASIC statement after the IRETURN before allowing the next interrupt wouldn't defeat the purpose of the interrupt.
It would allow the main code to get a look in even if interrupts were occurring rapidly; they would still be honoured and counted. But the interrupts wouldn't be able to lock out the main programme completely, as can happen at present. After all, the maximum delay before honouring the interrupt would be around an extra 0.5ms; half the minimum time taken for the (at least) two statements in the service routine.

Note that I am thinking of a way of preventing 'lockout' of the foreground routines that would be generally useful, rather than something tuned to your specific application. After all, what is the point of being locked into a perpetual series of interrupt servicing? The only way out would be to make everything happen in the service routine, which is not the way to go, or for the service routine to stop the interrupts, which loses the facility completely by re-allocating the pin function - probably not at all what is wanted.

Regards,
Bob
Bob Dalley
http://www.m0rjd.co.uk
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 01:57pm 26 Aug 2011
Copy link to clipboard 
Print this post

Hi All.

I have modified the firmware to add an extra configuration option (well sort of 2) to the SETPIN command.

The new options:

SETPIN pin,11,interrupt,count,mode
SETPIN pin,12,interrupt,count,mode

These are very similar to the current SETPIN pin,6,interrupt
and SETPIN pin,7,interrupt respectively.

The difference is that the interrupt routine will only be invoked when the number of pin changes (low to high for 11 and high to low for 12) reaches 'count'.

The mode option controls what happens when the count is reached. If mode is zero then the "pin" will stop counting, the current count (which should equal target!) is copied to MM.PCNT and the interrupt routine will be called once.

If mode is non zero, then the current count (which should equal target!) is copied to MM.PCNT and the current count is reset to zero. The interrupt routine is flagged for execution. When the target count reaches the target count again the process repeats.

I have also created a new function - PINCNT(pin) - which will return the current count if the pin is currently configured as 6,7,11 or 12. If not in these modes it returns 0.

I have uploaded the firmware and source in the same old spots (Maximite.hex, Source).

I have also modified the pump control program to utilise the new capabilities. The new program can easily handle all six channels operating at 1000Hz simultaneously and still continue to process the mainline code. The new program and also the test program I am using to simulate the pumps is here: Pump controller, Pump simulator

I am still undecided about the option of executing at least one MMBasic "mainline" statement in between every interrupt call.....

Enjoy!Edited by seco61 2011-08-28

Regards

Gerard (vk3cg/vk3grs)
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 02:10pm 26 Aug 2011
Copy link to clipboard 
Print this post

gerard do i need to run this hex code ..regards sparkey...pm me pls...thanks
technicians do it with least resistance
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 10:48pm 26 Aug 2011
Copy link to clipboard 
Print this post

Hi All

WOW, that is a HUGE change.
I don't have a second MM, but will test it today using the PC.
I haven't studied the code in detail yet,(will do today) but want to describe a scenario.

If the mode is Non-Zero and terminal count is reached, and the STOP output is ON, then any further counts recorded will be overshoot.The only way I will know that Target
was reached is by reading the Stop output pin.(or the StepNbr)
If the pump then stops dribbling and reached a count of say 100,
I will record a Total count as 10100.
Now I need to start a new load and reprogram that counter.
Does the new Setpin command set the counter to zero.?
In the 8254, it needs at least one pulse to do that, so in the PC software I always
delayed reading the counter for a few seconds.

The code is hard to read, but your comments are a great help.

Regards
Regards
Hervey Bay Qld.
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 02:15am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi.

Yes, the new SETPIN command with mode non zero does reset its counter to zero when the target is reached. BUT, it also sets MM.PCNT to the target value at the same time.

The code for the pump controller copies MM.PCNT to Cn when it executes its interrupt. It also copies Cn + PINCNT(pin) to On.

The checks at step 6 use Cn + PINCNT(pin) as the value so the "dribble" is counted and the correct total count is output when step 6 concludes. When step 6 concludes it also issues a SETPIN pin,0 comand and this halts the pin from further counting.

Anytime a SETPIN pin,[11,12],..... command is issued the target value is set and the internal counter is reset to zero. Also, issuing a SETPIN pin,[6,7],.... resets the target to zero.

And I have tested the the pump program with 6 simultaneous channels all being pulsed at 5kHz.

Again, the program outputs the 6 counts every 2 seconds and when the target was reached the "dribble" for each channel varied between 2 and 9 above the target. These "dribble" amounts are to be expected as at 5kHz the latency till the MMBasic interrupt routine that sets the pump off is executed will depend on the current MMBasic command that is being processed.

Overall, I think it now performs very well. This firmware is slightly faster than the v2.4 firmware.

HOWEVER - when I posted the firmware and source last night (just before the matches that were holding my eyes open broke...) there were a couple of bugs in that firmware/source. After 10 hours of sleep a quick look at the code this morning (with a mind that is now rested!) revealed a couple of stupid mistakes. The corrected firmware and source have now been posted in the regular place.

Please let me know if you find any issues...Edited by seco61 2011-08-28

Regards

Gerard (vk3cg/vk3grs)
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 02:48am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi All

Gerard, just added one line to allow me to get the Total(Step 7)count anytime before a new
cycle is started.
' TOTAL Count before new cycle is started.
1305 ? Format$(O1,"1,%05.0f,7,OK"):S1=-1:Exit
Will add to all 6 .
Still testing

Regards
Edit: The older you get ,(like a Dinosaur) the quicker you recognise when it is time
to Stop looking and let your sub conscious do the work for you.Edited by Dinosaur 2011-08-28
Regards
Hervey Bay Qld.
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 03:15am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi All

Gerard, have tested with all 6 counters paralel at 800 Hz, (don't have facility to do otherwise)
and set diferent Targets from C1,1500 to C6,1000 and after all were complete the result.
1,02996,7,OK
2,02792,7,OK
3,02591,7,OK
4,02396,7,OK
5,02188,7,OK
6,01992,7,OK
As I said, totally unrealistic test, so will have another go with 3, but would have expected a closer result.Note that I am simply winding the Amplitude back from 1.5 vdc to zero to stop pulsing, so that will introduce some errors.

Regards
Regards
Hervey Bay Qld.
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 03:18am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi.

Good idea - I have updated the pump control program with your change. It works as expected.


Regards

Gerard (vk3cg/vk3grs)
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 03:26am 27 Aug 2011
Copy link to clipboard 
Print this post

  Dinosaur said   Hi All

Gerard, have tested with all 6 counters paralel at 800 Hz, (don't have facility to do otherwise)
and set diferent Targets from C1,1500 to C6,1000 and after all were complete the result.
1,02996,7,OK
2,02792,7,OK
3,02591,7,OK
4,02396,7,OK
5,02188,7,OK
6,01992,7,OK
As I said, totally unrealistic test, so will have another go with 3, but would have expected a closer result.Note that I am simply winding the Amplitude back from 1.5 vdc to zero to stop pulsing, so that will introduce some errors.

Regards


As you are getting wildly different results to me, I suspect that your hardware test setup does not shutdown your "pulse generators" quickly.

I also ran the same test with my test Maximite generating 800Hz and the targets set from 1500 to 1000. Using a terminal macro so the start pump commands are issued very fast my results had channel 1-4 and 6 stopping at the target exacly and channel 5 at 1 over.

Edit:
Looking at your results it would appear that you do not have separate pulse generators - just using the one with its output paralled to all 6 inputs. Unless you are using some hardware in between to halt an individual channel when that channel's stop pump pin is set, the channel will keep counting pulses until step 6 has completed - ie it will keep counting as the input pulses are considered "dribble".
Edited by seco61 2011-08-28

Regards

Gerard (vk3cg/vk3grs)
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 03:27am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi All

Result for 3 only counters
1,02993,7,OK
2,02798,7,OK
3,02595,7,OK
Gerard, there must be something I am doing wrong, as with the method you desribed it should be able to handle 3 simultaneous Int at 800 Hz.

Regards
EDIT: I am issuing the commands with Hyperterminal in one string as in
C1,01500,2

C1,0,3

C2,01400,2

C2,00000,3

C3,01300,2

C3,00000,3

and then winding up the amplitude to start counting when all counters are reporting every 2 sec's. The odd thing is that each time C1 is the highest and C3 or C6 the lowest.
Edited by Dinosaur 2011-08-28
Regards
Hervey Bay Qld.
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 03:34am 27 Aug 2011
Copy link to clipboard 
Print this post

See my previous post (with its edit).

Regards

Gerard (vk3cg/vk3grs)
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 03:43am 27 Aug 2011
Copy link to clipboard 
Print this post

Also,

If you are stopping the pulse generator by manually reducing its output once the counters are in stage 6, it is VERY likely that the counters will have hit their target more than once (the counts gets reset to zero with mode non-zero and the process starts again). So the values you are getting would not reflect a real world situation where the pumps get a stop signal as soon as the target is reached.Edited by seco61 2011-08-28

Regards

Gerard (vk3cg/vk3grs)
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 03:56am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi All

Yeah, you are right.
By upping the Target to 10000 for each and screwing down the amplitude once the counters get to step -1, the difference is only 2 counts.(10624 to 10626)
So, I expect that when using separate pulses, the response will be perfect.

Gerard, now may be the time to re-comment the code and save it into the examples for other users.Although the software interface is different to the 8254, it is still a good replacement for 2 x 8254's, if you are counting pulses.

Will run a long term test over a few days, where the PC will issue commands and use an output relay to cut my sig gen.

Once again many thanks.

Regards
EDIT: I can do the comments to make it more generic if you like.Edited by Dinosaur 2011-08-28
Regards
Hervey Bay Qld.
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 04:32am 27 Aug 2011
Copy link to clipboard 
Print this post

hi trhere : well its also apprent in my inveter program that when i do hit q for qwit quit um the pin is still generating a pulse the only two ways to stop it press q to quit then type new the pulse stops or hit the power switch...regards sparkey :: here is the program:::also if i put a 1Kohm pulldown to earth would this stop the pin from floting at power up and so on ....

10 ' initialise I/O pins
20 voltpin = 1 'set analog voltage input pin (can be 1 - 10)
30 pwmpin = 8 'set the pwm output pin (can be 7 - 10)
40 freq = 100 'set initial frequency to 100Hz (can be 1 - 5000)
50 duty = 50 'set initial duty cycle to 50% (can be 0 - 100 in increments of 1)
60 offset = 0 'use to adjust for any offset in analog input
70 coefficient = 20 'use to scale the analog input
80 tick_avg = 100 'number of analog voltage samples to average each second
85 tick_flag = 0
90 tick_cnt = 0
95 DIM tick_array(tick_avg)
100 SETPIN voltpin,1 'configure pin for analog input
110 SETPIN pwmpin,10,freq,duty 'initiate PWM output
120 SETTICK CINT(1000/tick_avg),1100 'set tick interrupt for tick_avg per second
150 duty_str$ = "Enter duty cycle (0 - 100 for 0% - 100%), 'F' to change frequency or 'Q' to quit"
160 freq_str$ = "Enter frequency (1 - 5000 for 1 - 5kHz), 'D' to change duty cycle or 'Q' to quit"
200 CLS
210 volt = offset + (PIN(voltpin) * coefficient)
220 state = 1
230 LOCATE 0,24 : ? "Battery voltage =";
232 LOCATE 102,24 : ? FORMAT$(volt,"% .3fV ");
234 LOCATE 0,60 : ? "Running frequency =";
236 LOCATE 114,60 : ? freq; "Hz ";
238 LOCATE 0,96 : ? "Mark space ratio =";
240 LOCATE 108,96 : ? duty; "% ";
250 LOCATE 0,132 : ? duty_str$
300 DO WHILE state > 0
310 GOSUB 500
320 IF state = 1 THEN
330 IF number >= 0 AND number <= 100 THEN
332 duty = number : SETPIN pwmpin,10,freq,duty
334 ELSE
336 GOSUB 900 : ? number; " - Invalid duty cycle!" : PAUSE(1000) : GOSUB 900
338 ENDIF
340 ELSEIF state = 2 THEN
350 IF number >= 1 AND number <= 5000 THEN
352 freq = number : SETPIN pwmpin,10,freq,duty
354 ELSE
356 GOSUB 900 : ? number; " - Invalid frequency!" : PAUSE(1000) : GOSUB 900
358 ENDIF
360 ENDIF
370 LOCATE 102,24 : ? FORMAT$(volt,"% .3fV ");
375 LOCATE 114,60 : ? freq; "Hz ";
380 LOCATE 108,96 : ? duty; "% ";
390 LOOP
399 END
499 ' get number routine
500 GOSUB 900
510 DO WHILE 1
520 IF tick_flag = 1 THEN
521 tick_flag = 0
522 LOCATE 102,24 : ? FORMAT$(volt,"% .3fV ");
523 LOCATE 114,60 : ? freq; "Hz ";
524 LOCATE 108,96 : ? duty; "% ";
525 LOCATE LEN(numstr$) * 6,144
526 ENDIF
528 inpkey$ = UCASE$(INKEY$)
530 IF inpkey$ = "" THEN GOTO 520
540 IF inpkey$ = "Q" THEN state = -1 : EXIT
550 IF inpkey$ = "D" THEN
551 LOCATE 0,132
552 ? duty_str$
553 state = 1
554 GOSUB 900
555 GOTO 520
559 ENDIF
560 IF inpkey$ = "F" THEN
561 LOCATE 0,132
562 ? freq_str$
563 state = 2
564 GOSUB 900
565 GOTO 520
569 ENDIF
580 IF inpkey$ < "0" OR inpkey$ > "9" THEN
590 numlen = LEN(numstr$)
600 IF ASC(inpkey$) = 13 THEN
610 IF numlen = 0 THEN number = -1 ELSE number = VAL(numstr$)
620 EXIT
630 ELSEIF ASC(inpkey$) = 8 THEN
640 IF numlen > 0 THEN
650 IF numlen <> 1 THEN numstr$ = LEFT$(numstr$, numlen - 1) ELSE numstr$ = ""
660 csr = (numlen - 1) * 6
670 LOCATE csr,144 : ? " "; : LOCATE csr,144
680 ENDIF
690 ENDIF
700 ELSE
710 numstr$ = numstr$ + inpkey$
720 ? inpkey$;
730 ENDIF
750 LOOP
760 GOSUB 900
799 RETURN
899 ' clear input
900 numstr$ = ""
910 LOCATE 0,144
920 ? SPACE$(80)
930 LOCATE 0,144
999 RETURN
1099 ' settick interrupt routine
1100 tick_cnt = tick_cnt + 1
1110 tick_array(tick_cnt) = offset + (PIN(voltpin) * coefficient)
1120 IF tick_cnt <> tick_avg THEN IRETURN
1130 volt = 0
1140 FOR i = 1 TO tick_avg
1150 volt = volt + tick_array(i)
1160 NEXT i
1170 volt = volt / tick_avg
1180 tick_cnt = 0
1190 tick_flag = 1
1199 IRETURN
Edited by sparkey 2011-08-28
technicians do it with least resistance
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 05:38am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi Brian.

Add the following line if you want the PWM output to stop when you press 'Q':


395 SETPIN pwmpin,0


This will set the pin as an input.

By default, all pins are set as input at power on. This is a high impedance state.

If you want to ensure the pin is low then a pulldown resistor will do the trick. The value you use will depend on the source impedance of the load you are driving but somewhere between 1K and 10K would normally do the trick.

Regards

Gerard (vk3cg/vk3grs)
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 06:34am 27 Aug 2011
Copy link to clipboard 
Print this post

Mmmm...

I have modified the SETPIN command to accept 3 different values for mode (ie for SETPIN pin,[11,12],interrupt,target,mode).

The functions of each setting:

0 - When the target is reached, the MMBasic interrupt is flagged to run. Just before the MMBasic interrupt routine is invoked, counting is stopped and MM.PCNT will report the value of the count at this point in time. The value could be higher than target depending on the time taken for the MMBasic interrupt routine to scheduled. PINCNT(pin) will also return the value of the counter.

1 - When the target is reached, the count is reset to zero and the MMBasic interrupt is flagged to run. MM.PCNT will be set to the target value. Counting will continue and the interrupt routine will be flagged again when the target is reached, as before. PINCNT(pin) will always report the current value of the counter.

2 - When the target is reached, the MMBasic interrupt is flagged to run. Counting continues. When the interrupt runs MM.PCNT will return the current value of the counter. PINCNT(pin) will always report the current value of the counter. The count will continue counting until another SETPIN command is issued. If the count should overflow, it will start at zero again and when the target is reached another interrupt will be scheduled. However, the count field is a 32 bit unsigned data type, so the max value before overflow is 4,294,967,295.

The target field will accept a maximimum value of 4,294,967,000, but due to storage as a float by MMBasic the actual number stored will only be an approximation once the value exceeds 16,777,100.

I have changed the pump controller program to use the mode 2 value.

Code is here: pump controller, firmware, source

Regards

Gerard (vk3cg/vk3grs)
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 06:35am 27 Aug 2011
Copy link to clipboard 
Print this post

u know the first thing i thought of when i say the maxi was ::can i get this thing to run my inverter and with what we have acchived its pretty cool so far with experimentation comes necessaty and with this comes invention we will get this thing flying in due corse i was well pre paired when i even had first thoughts that there would be slip ups and melt downs i gave thought that something electronic is never perfected till it reaches its full potentional and with this in mind we forge ahead only to look back to gather knowadge to inspire the future,,,...regards ...
technicians do it with least resistance
 
Dinosaur

Guru

Joined: 12/08/2011
Location: Australia
Posts: 304
Posted: 07:00am 27 Aug 2011
Copy link to clipboard 
Print this post

Hi All

Gerard, I have only just managed to get the counters to operate via PC on a repetative basis. But I am getting weird results occasionally, so won't comment further until
I have tested your latest code, probably tomorrow. The red wine is calling.

Regards
Regards
Hervey Bay Qld.
 
sparkey

Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 819
Posted: 07:08am 27 Aug 2011
Copy link to clipboard 
Print this post

thanks gerard it takes a second or two but returns to 0 volt will fit a resistor thanks again ...regards...
technicians do it with least resistance
 
seco61
Senior Member

Joined: 15/06/2011
Location: Australia
Posts: 205
Posted: 08:01am 27 Aug 2011
Copy link to clipboard 
Print this post

  seco61 said  The target field will accept a maximimum value of 4,294,967,000, but due to storage as a float by MMBasic the actual number stored will only be an approximation once the value exceeds 16,777,100.


I just did some checking to see what MMBasic would accept as the largest integer value:

The largest value accepted is 2,147,483,583 - however the number that is stored for this value is 2,147,483,520 due to the storage of numbers as 32 bit floating point numbers.

Regards

Gerard (vk3cg/vk3grs)
 
     Page 6 of 7    
Print this page
© JAQ Software 2024