Hello and question

Hi all, just got a picaxe 08m setup, never really dabbled in microcontrollers before, but got the setup working and successfully uploaded some of the samples. Good stuff!

Right so now I am at the stage where I want to try a few simple things, here is what I'd like to try:

Have a digital input be read and have one output go high at half the frequency, and another output go high at a quarter of the frequency, eventually adding the option to have other divisions, but initially just keeping it simple. Edit - The digital input is currently connected to a function generator, outputting a square wave, so transitions from high to low. So far I have got this, but not sure what to do next.

Code:
init:
SYMBOL trig_in = pinc.2
main:
IF trig_in = 1 THEN
Any help gratefully received!
 
Last edited:

sghioto

Senior Member
Welcome to the forum buzzlightyear.

Sounds like you are trying to program a digital divider. I'm assuming you mean to turn the outputs OFF as well. So every second pulse turns output 1 ON then OFF and every 4 pulse turns output 2 ON then OFF. So something like this might work using the variables b1 and b2 to store the pulse count

Code:
main: if pin2 = 0 then goto main
      if pin2 = 1 then
      inc b1
      endif
      if b1 = 2 then
      high 0
      endif
      if b1 = 4 then
      low 0
      high 1
      endif
      if b1 = 6 then
      high 0
      endif
      if b1 = 8 then
      low 0
      low 1
      b1 = 0
      endif
      do 
      if pin2 = 0 then 
      goto main
      endif
      loop
Steve G
 
Last edited:

geoff07

Senior Member
Count the pulse high and low transitions as they occur, then using modulo (//) divide by 2 and by 4 and when the remainder is 0, cause the /2 or /4 output to also transition the same direction. In future, you can add in any other division ratio.
 
Thanks guys, basically yes just a frequency divider that goes high/low at divisions of the input pin, so if input was LHLHLHLH on divide by 2 it would be LHLH on divide 4 it would be LH.
Ideally I'd want it to go upto about 3Khz. So lets say I set pin C.4 output as input C.2 divide by 2, and pin C.1 as input C.2 divide by 4, so if I send a 2Khz square wave (4v) into C.2 and get 1Khz out from C.4, and 500Hz from C.1 - does this seem feasible?
 
Thanks, I just tried it and the output frequency is the same as the input (in this case 1khz) I tried both the outputs and they are the same, I'm sending into pin 2 a 50% duty cycle squarewave at 4v amplitude, and using a 10k pulldown resistor (I tried it without the resistor also, no change) Any ideas?
 

sghioto

Senior Member
It's not working. I'm getting division by 4 and 8 instead of by 2 and 4, and it's not synced with the input, but certainly not the same frequency on the outputs. Anyway the code is flawed, forget about it.:p

Steve G
 
Hah, well thanks for trying, I'm wondering if the output I'm getting is just the function generator bleeding through, I am monitoring it with a speaker so it might well be a hardware issue too:confused:

I might try something more basic based on your code, perhaps just a single output dividing by 2, and I might try a lower input frequency.
 

AllyCat

Senior Member
Hi,

For the "simple" situation of binary counting, you can just transfer the count to (or create it in) W0 and then read off the "divided" signals using bit0, bit1, etc.. For example (seems to work in the simulator):
Code:
    low c.0,c.1,c.2
do
    inc w0
    pinc.0 = bit0
    pinc.1 = bit1
    pinc.2 = bit2
    pause 1000
loop
Or if the pin numbers map easily (as above), then you could use pinsc = w0 which is faster.

Cheers, Alan.
 
Aha, some success!

I tried your code Alan in the sim and it seems to be doing what I want, then I modified it to have pinc.4 increment like this
low c.0,c.1,c.2
do
if pinc.4 = 1 then inc w0
endif
pinc.0 = bit0
pinc.1 = bit1
pinc.2 = bit2
loop
And it appears to be working;) Getting late now so I will test further tomorrow, thank you!
 
Follow up, it is not working as desired, what is happening is that the output pins are rapidly going from L-H for the duration that the input is high, damn!
 

sghioto

Senior Member
That's because w0 is constantly incremented when the input is high. It needs to increment only once each time the input goes high. I tried this code but even at 8 mhz was only good to 500 hz. on a 08M. BTW are you using a 08M or 08M2?

Steve G.

Code:
 setfreq m8
main:
      pulsin 3,1,b0 
      inc b2
      let pins = b2
      goto main
 

AllyCat

Senior Member
Hi,

Yes, you need to wait somewhere in the loop for the button to be released. For example do : loop until pinc.4 = 0.

In applications like this, you often need the program to look for a "transistion", (i.e. a change in a value), so you can use variables which contain the "last" value as well as the "present" value and a test such as if present > last then {dosomething} : last = present : endif.

For general "counting" to any base you can use something like:

Code:
do
   inc b0
   if b0 > 9 then
       b0 = 0
         inc b1
         if b1 > 9 then
;          .....  etc.
         endif
     endif
   pause 100    ;  Or wait for another "event"
loop
Cheers, Alan.
 
That's because w0 is constantly incremented when the input is high. It needs to increment only once each time the input goes high. I tried this code but even at 8 mhz was only good to 500 hz. on a 08M. BTW are you using a 08M or 08M2?

Steve G.

Code:
 setfreq m8
main:
      pulsin 3,1,b0 
      inc b2
      let pins = b2
      goto main
I'm using 08m2
 
Hi,

Yes, you need to wait somewhere in the loop for the button to be released. For example do : loop until pinc.4 = 0.

In applications like this, you often need the program to look for a "transistion", (i.e. a change in a value), so you can use variables which contain the "last" value as well as the "present" value and a test such as if present > last then {dosomething} : last = present : endif.

For general "counting" to any base you can use something like:

Code:
do
   inc b0
   if b0 > 9 then
       b0 = 0
         inc b1
         if b1 > 9 then
;          .....  etc.
         endif
     endif
   pause 100    ;  Or wait for another "event"
loop
Cheers, Alan.
Ah makes sense, basically what I am trying to achieve is that the input pin is attached to an external squarewave generator which has variable frequency, then to have output pins divide the frequency and give me squarewave outputs, the range needs to be from 40hz to 3khz.
 

sghioto

Senior Member
basically what I am trying to achieve is that the input pin is attached to an external squarewave generator which has variable frequency, then to have output pins divide the frequency and give me squarewave outputs, the range needs to be from 40hz to 3khz.
This is only an exercise correct? I mean you could do this better with any divider chip like a CD4017:)

Steve G
 
I think this is what I want to do, but the code is obviously wrong, but I am posting it as a idea of the process
'note does not work!!! bad syntax
main:
b0 = 0
low c.2
do
if pinc.4 = 1 then inc b0
endif
if b0 > 4 then 'return b0 to zero
if b0 = 1 'then set c.2 high
if b0 = 2 'then set c.2 low
if b0 = 3 'then set c.2 high
if b0 = 4 'then set c.2 low
endif
goto main
So that is essentially what it should be doing right?
 
Would pulsin and pulsout be more suitable to use, so read pulsin and multiply by 2 for the value of pulsout? That should be the same principle of having the output half of the input, correct?
 

AllyCat

Senior Member
Hi,

Pulsin and Pulsout are "blocking" commands (they can't "overlap") so not likely to be useable.

For 3 kHz you will need a very "tight" program loop if using a PIcaxe, even at a 32 MHz clock frequency (Setfreq m32). Probably as shown in #11, but using the pinsc = w0 command, and fast testing of the input pin, (e.g. a tight loop which looks for a positive edge) and then jump out to increment/report the count.

But as Steve says, much easier with a dedicated hardware counter.

Cheers, Alan.
 
I was actually trying to avoid using a dedicated chip, but yeah in usual circumstances would be a lot easier. I wonder if just having a single output would be easier, in that case what do you guys think would be the proper way to do it? I do not know the issues of running the chip at 32mhz but I guess it would burn through batteries a bit quicker? Any other downsides?
 

sghioto

Senior Member
"Pulsin" seems to work better then using "if pin3 = 1", example:

Code:
setfreq m32         
low 0,1,2


main: if pin3 = 0 then goto main
        inc b0
        let pins = b0
     
loop1: if pin3 = 0 then goto main
         goto loop1
This works up to almost 1700 hz but with a slight jitter on the outputs
No jitter using this code:

Code:
 setfreq m32
main:
        pulsin 3,1,b0 
        inc b2
        let pins = b2
        goto main
You haven't answered my last question if this just an exercise or not.

Steve G
 
Sorry Steve, kind of yes an exercise, basically I bought a few picaxe chips to play around with since they are affordable and (supposedly ;) ) the simplest micro controller to use, then thought of applications that I might find useful and see if they are possible, in the meantime I am also trying out a few of the examples and trying to wrap my head around it all.

So this application is basically to try to make a sub-oscillator for a homemade synthesizer.
 
Top