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 KingdomPosts: 41 |
Hi Dinosaur, 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: AustraliaPosts: 205 |
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! Regards Gerard (vk3cg/vk3grs) |
||||
sparkey Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 819 |
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: AustraliaPosts: 311 |
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: AustraliaPosts: 205 |
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... Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
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.
Will add to all 6 .
1305 ? Format$(O1,"1,%05.0f,7,OK"):S1=-1:Exit 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. Regards Hervey Bay Qld. |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
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
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.
2,02792,7,OK 3,02591,7,OK 4,02396,7,OK 5,02188,7,OK 6,01992,7,OK Regards Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
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: AustraliaPosts: 205 |
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". Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
Hi All Result for 3 only counters 1,02993,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.
2,02798,7,OK 3,02595,7,OK Regards EDIT: I am issuing the commands with Hyperterminal in one string as in C1,01500,2
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.
C1,0,3 C2,01400,2 C2,00000,3 C3,01300,2 C3,00000,3 Regards Hervey Bay Qld. |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
See my previous post (with its edit). Regards Gerard (vk3cg/vk3grs) |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
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. Regards Gerard (vk3cg/vk3grs) |
||||
Dinosaur Guru Joined: 12/08/2011 Location: AustraliaPosts: 311 |
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. Regards Hervey Bay Qld. |
||||
sparkey Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 819 |
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 technicians do it with least resistance |
||||
seco61 Senior Member Joined: 15/06/2011 Location: AustraliaPosts: 205 |
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: AustraliaPosts: 205 |
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: AustraliaPosts: 819 |
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: AustraliaPosts: 311 |
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: AustraliaPosts: 819 |
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: AustraliaPosts: 205 |
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 |