The worst programmer ever to grace this forum - ME!


Closed Thread
Page 1 of 2 12 LastLast
Results 1 to 40 of 50
  1. #1
    Join Date
    Mar 2009
    Posts
    653

    Default The worst programmer ever to grace this forum - ME!

    Ok, I've been on about 8 hours trying to get a damn LED to light using PICBAsic - nothing!

    I have a PICkit 2 (the board comes with a PIC16F690), everything works fine with 'hello world' tutorial Microchip provide (which proves the chip & LED is fine). Assembly language make my brain spontaneously combust so I would like to learn a higher level language such as basic (which seems at least a little akin to DEC DCL...something I used about 10 years ago)...I'm beginning to wish I hadn't.


    Right to my simple problem - more than anything in the world right now, I want to see that stupid little LED on my PICkit 2 low pin count board light up!

    Most of the 'flash an led' example basic programs work on the PIC's Port A...now I thought it would be a simple case of changing the references conatined therein to PortC (the 4 leds on the Pickit board are attached to Port C)

    But when I change not a lot happens!

    I'm aware that the 16f690 has analogue ports turned on as default & Ive seen some mention that this can be remedied with a commands along these lines

    ANSEL = 0
    ANSELH = 0

    but the microcode studio GUI doesn't seem to recognise those commands (I'm new to this interface but it seems to darken/bold commands it's happy with)

    Could some one humour me here & cut/paste in the ludicrously simple basic code for PIC Basic Pro that I need to light an LED on portc.1 of my 16f690.

    I can then put this all to rest & pour petrol over my pickit 2 whilst moonwalking backwards to "The eye of the Tiger".




    FWIW, This is the latest code I've tried (based on this link http://www.digital-diy.net/16F%20Exa...LED's.aspx )....

    Symbol LED_1 = PortC.0 ' Define a symbol in the program

    TRISC.0 = 0 ' Make PORTC.0 an output
    PORTC.0 = 0 ' and set it low (0V)

    Main:

    If LED_1 = 0 then ' Check the status of the LED
    LED_1 = 1 ' and toggle it
    Else
    LED_1 = 0
    Endif

    DelaymS 1000 ' Delay for 1 second (compiler errors with this line - I guess the command isn't right!)
    Goto Main ' Loop forever




    Basic Schhmasic....
    Last edited by HankMcSpank; - 14th March 2009 at 00:41.

  2. #2
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Here, this chaser works with the hardware you are using:
    MPASM required, you must comment out the config in the .inc file for 16f690 in PBP root.
    Code:
    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON  
    @MyConfig = MyConfig & _MCLRE_ON & _BOR_OFF 
    @ __config  MyConfig 
    
    DEFINE OSC 4
    PortA = 0
    PortB = 0
    PortC = 0
    TRISA = 0
    TRISB = 0
    TRISC = 0
    i var byte
    
    main:
    portc = 0
    pause 500
    for i = 1 to 15; step -1
    portC = i
    i=i  << 1 
    pause 250
    next i
    goto main
    end
    Here's a blinkey:
    Code:
    DEFINE OSC 4
    PortA = 0
    PortB = 0
    PortC = 0
    TRISA = 0
    TRISB = 0
    TRISC = 0
    
    LED_1 var PortC.0 ' Define an alias in the program
    led_1 = 0
    
    Main:
    HIGH LED_1
    PAUSE 1000
    LOW LED_1
    PAUSE 1000
    Goto Main ' Loop forever
    end
    OK here is your code reworked:
    Code:
    DEFINE OSC 4
    LED_1 VAR BIT  ' PORT FLAG BIT
    LED_1 = 0      ' SET INITIAL VALUE
    TRISC.0 = 0 ' Make PORTC.0 an output
    
    
    Main:
    IF LED_1 = 0 THEN
    LED_1=1
    ELSE
    LED_1 = 0
    ENDIF
    PORTC.0 = LED_1
    
    
    
    
    PAUSE 250 ' Delay for 1 second (compiler errors with this line - I guess the command isn't right!)
    Goto Main ' Loop forever
    It appears as though the PIC cannot read and change it's own output without an intermediary like a flag variable. Probably
    A RMW thing, I do not know.
    Last edited by Archangel; - 14th March 2009 at 02:07.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok, many thanks for helping me.

    When I enter the code you recommended below *and*comment *all* the entries in the 16f690.inc (c:\PBP) I get 121 compiler errors (I have MPASM selected under the assembler tab ...I'm using the defaul selections when I select MPASM eg INHX8SM)...


    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
    @MyConfig = MyConfig & _MCLRE_ON & _BOR_OFF
    @ __config MyConfig

    DEFINE OSC 4
    PortA = 0
    PortB = 0
    PortC = 0
    TRISA = 0
    TRISB = 0
    TRISC = 0
    i var byte

    main:
    portc = 0
    pause 500
    for i = 1 to 15; step -1
    portC = i
    i=i << 1
    pause 250
    next i
    goto main
    end


    but when I reenable all the comments in the .inc file, i only get 2 errors (relating to line 63 in the corresponding asm file - if my counting is correct, it's this line __config MyConfig ....is there an easier way to establish the line that's erroring from what's being reportred in the results field?)
    Last edited by HankMcSpank; - 14th March 2009 at 10:16.

  4. #4
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    When I enter the code you recommended below *and*comment *all* the entries in the 16f690.inc
    http://www.picbasic.co.uk/forum/showthread.php?t=543
    Dave
    Always wear safety glasses while programming.

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    To me, that FAQ assumes a fair degree of previous knowledge!

    if I'm reading it right, the 16F690.inc file tells the assembler to configure the PIC for 'what's out there'?

    What's doing my head in is the sheer number of 16f690.inc files there are on my PC...

    c:\mpasm\16f690.inc (which looks a whole lot different to the others!)

    c:\pbp\16f690.inc (the one that Joe S said I should comment out - not sure which lines ...all of them?)

    c:\pbp\inc\ (a whole lot of files in here!)


    At the risk of sounding incredibly slow - help!

    Once again, all I want is the correct code to 'set the chip correctly' for me to then start my simple journey to get an LED, firstly lit, then flashing (wheee!)

    Joe.S kindly posted a 'chaser' earlier ( & said I needed to comment out the inc file in c:\pbp ....which lines?!)

    I'm perplexed that this chip should be so troublesome at the very first base ....from a newbie's perspective, it's probably the most prevelant since it's bundled in with the low pin count board on on the Pickit 2 starter. It might have been useful to have a "So you got a 16F690 PIC & you've arrived here after using the Pickit 2....here are some things you should know/do!" type thread.

    I'm an absolute novice here.....are we saying there's an issue with the PIC itself...or just this particular PIC in combination with PICBasic? (fwiw, I'm suspecting the latter as the PIC is fine using the Micropchip Assembler)

    Many thanks in anticipation.
    Last edited by HankMcSpank; - 14th March 2009 at 14:41.

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    In your 16F690.INC only comment out the __config line. Leave everything else
    as-is.

    Then something like this should work if you're disabling analog inputs & comparators;
    Code:
    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON  
    @MyConfig = MyConfig & _MCLRE_ON & _BOR_OFF 
    @ __config  MyConfig 
    
    DEFINE OSC 4
    
        i var byte
        
        ANSEL=0      ' all digital
        ANSELH=0     ' analog module disabled
        CM1CON0=0
        CM2CON0=0
        PortC = 0
        TRISC = 0
    
    
    main:
        portc = 0
        pause 500
        for i = 1 to 15
        portC = i
        pause 150
        next i
        goto main
        end
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  7. #7
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hey Bruce...that compiled without errors! (which is progress in my books! A big thanks to Joe.S too, as it's pretty much as he said...just naivity wrt commenting out the inc file on my part)

    Can someone explain what's actually going on with the looping part though....

    main:
    portc = 0
    pause 500
    for i = 1 to 15
    portC = i
    pause 150
    next i
    goto main


    It looks like it's setting port C output to be low, waiting 500 (milliseconds?), the making PRT C = i .....what's that "i" melarkey all about?!!


    Still no sign of life from the LED on my PICkit 2 board though (though I'm figuring Port C needs to be set high at some stage ....by the way, why no use of PORTC.0 or PRTC.1 here...ie nominating the actual chip pin RC0, RC1 etc?)

    tks,
    Hank.
    Last edited by HankMcSpank; - 14th March 2009 at 15:06.

  8. #8
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post

    Can someone explain what's actually going on with the looping part though....

    main:
    portc = 0
    pause 500
    for i = 1 to 15
    portC = i
    pause 150
    next i
    goto main


    It looks like it's setting port C output to be low, waiting 500 (milliseconds?), the making PRT C = i .....what's that "i" melarkey all about?!!


    Still no sign of life from the LED on my PICkit 2 board though (though I'm figuring Port C needs to be set high at some stage ....by the way, why no use of PORTC.0 or PRTC.1 here...ie nominating the actual chip pin RC0, RC1 etc?)

    tks,
    Hank.
    Last things first, The code assumes the port arrangement is from lowest order portc.0 to highest order portc.7 in its display of count. The i is just a name for the variable storing the count, you can rename it HankMcSpank and it will work the same, it is just easier to use i. So you have a variable storing a binary count to 15, the i=i<<1 is there to alter the light sequence so you do not have any dark leds in between lit ones. Try commenting it out and you will see it count in binary. Change the 15 to seven and it will only light 3 LEDs.
    <br> Now as for no signs of life from your LEDs, in the PICkit2 programmer software there is a check box that must be selected to power your demo board, unless you rig a separate power line to it.
    <br>__config MyConfig is a trick I picked up from Darrel so as to avoid having my config statement run off the reservation (the page). This is especially helpful if you print your code for archival purpose. You can, and most do put it all on one line like so:<br>@ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BOR_OFF

    Edit: I initially misunderstood last question.
    Last edited by Archangel; - 14th March 2009 at 19:30.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  9. #9
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Joe S. View Post
    <br> Now as for no signs of life from your LEDs, in the PICkit2 programmer software there is a check box that must be selected to power your demo board, unless you rig a separate power line to it.
    VDD *is* present (ie I double checked, by testing the VDD test point with my Voltmeter ....when I added the Pickit 2 to PICBASIC, I quickly established that -T needed to be added to the parameter field to keep VDD on the board when the programming sequence exited.

    My LEDS are doing anying!

    Could you please outline what bit of code would need to follow your 'chaser' to raise all RCx ports high? ...

    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
    @MyConfig = MyConfig & _MCLRE_ON & _BOR_OFF
    @ __config MyConfig

    DEFINE OSC 4
    PortA = 0
    PortB = 0
    PortC = 0
    TRISA = 0
    TRISB = 0
    TRISC = 0
    i var byte


    ....I'll settle for *any* illuminated LED at this stage! (flashing or not).

    The PICkit 2 board has an LED connected to pins RC0-RC3. (btw: I can handle references like PORTC.0 PORTC.1 ...but at this stage, I'm just not locking in to referencing the Port C pins on the PIC in other ways!)



    PS As a sanity check, I've just programmed up the PIC with the Microchip "rotate" hex code....all LEDs light up & chase just fine.
    Last edited by HankMcSpank; - 14th March 2009 at 20:25.

  10. #10
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    _MCLRE_OFF
    ???
    I do not have the board you have, just maybe..
    Dave
    Always wear safety glasses while programming.

  11. #11
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    _MCLRE_OFF
    ???
    I do not have the board you have, just maybe..
    BINGO! That was it!!! Many thanks to you all!!

    For the record, anyone else with a PICkit 2 board (with a PIC16F690) .....to save you hours of puzzlement...

    In your C:\PBP\16F690.INC , comment out this one line (thanks to Bruce)...

    ; __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF

    Put all of the following code at the top of your PICBASIC programming window (thanks to mackrackit for the _MCLRE_OFF tip)...

    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
    @MyConfig = MyConfig & _MCLRE_OFF & _BOR_OFF
    @ __config MyConfig

    DEFINE OSC 4

    i var byte

    ANSEL=0 ' all digital
    ANSELH=0 ' analog module disabled
    CM1CON0=0
    CM2CON0=0
    PortC = 0
    TRISC = 0



    And if you have - like I have - a burning desire to see your board's LEDs light in sequence, add this bit of code (thanks to Joe.S)...

    main:
    portc = 0
    pause 500
    for i = 1 to 15; step -1
    portC = i
    i=i << 1
    pause 250
    next i
    goto main
    end



    What's a beginner to do?!!! Most of this was (is!) double dutch....a what with a day & a half's effort just to get LEDs lit with the simplest of basic code....I think my programming interest is going to wane very fast!.

    Now to my main intention, a simple PIC based 'pulse counter' program for a coil winder.

    If your interested, you can read about what I'm trying to achieve here ....

    http://www.electro-tech-online.com/m...am-needed.html

    (you can see my appeal for the simple PIC program didn't get much of a response, hence me having to darken this forum's doorstep and try to figure it all out myself!)
    Last edited by HankMcSpank; - 15th March 2009 at 01:08.

  12. #12
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Huh, that's funny, I copy pasted that from MCS on my computer, and it works splendidly with MCLRE_ON, I can reset MCLRE on the programmer using the little check box and that works too.<br>
    Glad Dave got you going !
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  13. #13
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Just got hit with the next 'gotcha'!

    I was trying to get an LED to light up when the button on my low pin count was pressed - just spent ages trying to figure out why the LED wouldn't light. A check with my voltmeter revealed no matter code I tried, RA3 was always held low, a bit of Googling revealed this...

    http://www.microchip.com/forums/tm.aspx?m=270347


    F: Pushbutton doesn't work with Low Pin Count (LPC) or 28-Pin Demo Boards
    The pushbutton cannot be used on these demo boards when debugging or programming and powering them from the MPLAB IDE. The pushbutton switch is connected to the input pin that is shared with the nMCLR/VPP pin. When Debugging, this pin must be used as nMCLR and cannot be used as an input pin. When programming and leaving the PICkit 2 connected to the Demo Board to power it, the MPLAB IDE always maintains a valid output state on a programmer's nMCLR/VPP pin which prevents the switch from changing the signal value. Use the PICkit 2 Programmer software to allow the switch to be used.


    It seems I now have to assemble, & then fire up PICKit 2 to wrtie the hex to the PIC (button works as it should then).

    Mindboggling for a beginner like me, ie that there should be so many 'enviromental' hurdles to get over, when all I want is to learn the most simple of code!
    Last edited by HankMcSpank; - 15th March 2009 at 10:03.

  14. #14
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    I will suggest you pick up a cheap bread board or two and a hand full of LEDs, resistors, caps etc. The demo boards are nice I guess, but you can not do a whole lot with them other than what they were designed to do.

    As far as the coil winding project goes. A switch on a cam or some other part will work. Every revolution the switch is "bumped" from low to high. Every time the switch is bumped a variable is incremented.

    If it is not running real fast interrupts will not be needed.
    Code:
    LOOP:
    IF SWITCH = 1 THEN
    WRAP = WRAP + 1
    GOTO LOOP
    That is the basics. Add a serial or LCD to display the value. Add
    IF WRAP = X THEN GOTO STOP ???

    Let us know...
    Dave
    Always wear safety glasses while programming.

  15. #15
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    I will suggest you pick up a cheap bread board or two and a hand full of LEDs, resistors, caps etc. The demo boards are nice I guess, but you can not do a whole lot with them other than what they were designed to do.

    As far as the coil winding project goes. A switch on a cam or some other part will work. Every revolution the switch is "bumped" from low to high. Every time the switch is bumped a variable is incremented.

    If it is not running real fast interrupts will not be needed.
    Code:
    LOOP:
    IF SWITCH = 1 THEN
    WRAP = WRAP + 1
    GOTO LOOP
    That is the basics. Add a serial or LCD to display the value. Add
    IF WRAP = X THEN GOTO STOP ???

    Let us know...
    Whilst I was sold on the concept of the ease of use of the Microchip low pin count board, (esp to get me some simple quick & dirty IO) I'm now very rapidly seeing the shortcomings!

    As it goes I have, breadboard & plenty of components...I'll be using all that in earnest, once I've nailed the basics here (no pun intended).

    Re the coil winder. I'm using an old DC cooling fan with a drill chuck hot glued to its centre ( http://img25.imageshack.us/img25/2717/workshopjd8.jpg - ugly but fulfills a need!)....this drill chuck will hold the 'solenoid core' while to copper wire is wound onto it. On this fan will be 7 or so magnets, each in turn closing a magnetic reed switch as the motor turns (I'd imagine the maximum speed the fan will be turning at for this project will be about 200RPM I've made a simple PWM circuit to control the speed of the fan).

    Where the PIC comes into the equation, is that it will count the pulses from the fan motor. For every 'X' pulses it receives from fan motor's reed switch, the PIC will send one short pulse onwards to a UCN5804 stepper motor IC. It's essentially a pulse counter/divider ...for ever x pulses received, output one pulse.

    The UCN5804 feeds a small stepper motor - on its shaft is a bit of threaded nylon rod - it's over this threaded rod that the copper wire feeds onto the solenoid core (this youtube video illustrates what I'm trying to achieve well - (from about 27 seconds in).

    The whole point of this is to have my wire neatly wound onto the solenoid. Since I know the diameter of the copper wire (0.15mm), & I know the pitch of the nylon rod's thread feeding the wire (1mm), it's just a fairly simple calculation. therefore for every turn of the main DC fan, I need the stepper motor threaded rod traverse the wire 0.15mm. It's a 7.5deg stepper, therefore each step of the 1mm pitch threaded rod will traverse the copper wire 0.0208mm, therefore to move the wire 0.15mm, some 7.2 steps needed are to the stepper for every turn of the main fan (since there's no such thing as 0.2 of a pulse I'll be rounding it down to 7!)

    To nail this project I need to...

    1. Sort out all the idiosyncracies of getting my PIC programming enviroment set up for the PIC16F690 - check! (thanks to here!)
    2. Lean how to set a PIC output pin high - check!
    3. Learn how to check a PIC input pin (to see if a switch has closed) - check!
    4. Learn how to setup a few 'count' variables, get them incrementing (& check 'em)....acting whenever the counts have been met - still to do!
    5. Learn how to output a pulse - still to do.

    I'll also need to figure out some form of debounce (I may end up using a monostable chip to do this)

    Thanks for your suggestion on how to approach this...I'll have a play with your lines to see if I can get the switch on my low pin count board to act as the reed switch & one of the LEDs as the stepper chip feed....ie after 7 presses of the board's button, make an LED turn on.
    Last edited by HankMcSpank; - 15th March 2009 at 13:51.

  16. #16


    Did you find this post helpful? Yes | No

    Default

    do the debounce in software. (short pause) or if it's off to do something else once triggered, you may not even need debounce..

    you can search for debounce examples from here http://www.picbasic.co.uk/forum/showthread.php?t=4751

  17. #17
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok, a bit more reading .... it seems the button command will be perfect for needs.

    My initial problem is that it only acts on PORTB pins (& the Pickit 2 board has its switch wired to RA3). therefore I've rigged up a pull up resistor onto pin RB7 & a small switch which goes to ground (therefore puts 0V onto RB7 when this new switch pressed). However RB7 is being held low all the time.

    I'm figuring this must be something to do with the .inc file again (I've rechecked my wiring - it's fine ...10k resistor between RB7 & the 5V rail....and a normally open switch going from RB7 to ground). I chose RB7 for my new switch as it seemed to have the least happening! On the datasheet it's listed as RB7/TX/CK ...how can I be sure it's being used as an input pin only (& not being overridden by one ithe pins other purposes)

    Does anyone have any ideas why my RB7 might be permanently low.

    Here's the small bit of code I'm using...

    @MyConfig = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON
    @MyConfig = MyConfig & _MCLRE_OFF & _BOR_OFF
    @ __config MyConfig

    DEFINE OSC 4
    ANSEL=0 ' all digital
    ANSELH=0 ' analog module disabled
    CM1CON0=0 ' dunno what this line does!
    CM2CON0=0 ' nor this one!
    TRISA=%11111111 ; set all Port A pins as inputs
    TRISB=%11111111 ; set all Port B pins as inputs
    TRISC=%00000000 ; set all Port C pins as outputs

    B0 VAR BYTE ;creates a variable as needed for the button command below
    B0 = 0 ; give it a value of zero (as per the command's reference)

    LED1 var PortC.0 ' ; assign a more usable name to the first LED port

    start:
    LOW LED1 ; turn the first LED off

    BUTTON 7, 0, 255, 0, B0, 1, Loop ; monitor the switch on RB7 for 0V,
    ;if this condition is net, then go to next

    next:
    high LED1 ; turn the first LED on
    PAUSE 1000 ; wait one second
    goto start ;start over
    End
    Last edited by HankMcSpank; - 16th March 2009 at 00:39.

  18. #18
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    BUTTON 7, 0, 255, 0, B0, 1, Loop
    ???????
    Try
    BUTTON PORTB.7, 0, 255, 0, B0, 1, Loop

    Or better yet
    Code:
    IF PORTB.7 = 0 THEN GOTO NEXT
    OOPS!!!!!!
    That will not work...NEXT is a reserved word. Will have to think of something else to call that label.. FRED??
    Dave
    Always wear safety glasses while programming.

  19. #19
    Join Date
    Mar 2009
    Location
    San Diego, CA USA
    Posts
    3


    Did you find this post helpful? Yes | No

    Default 'F690 Registers and BUTTON Code

    HankMcSpank,

    I think the 'F690 is going to be my next favorite PIC. It has SO MUCH STUFF on it!
    In other words, not a beginner PIC ( like the 16F628, F648, F87, F84(old and gray) )
    There are ALOT of registers to learn how to use on this chip.

    NOTE: something that used to trip me up when reading data sheets:
    when you "SET" a value you change it to "1"
    when you "CLEAR" a value you change it to "0"
    so that if someone says "set the flag", it means to ONE, (1), HIGH
    I only bring this up because you are new. The M-chip data sheets use this nomenclature all the time.

    Also NOTE: The 16F690 Datasheet is your new best friend. All 306 pages, WOW. You might want to print out the pages with
    the register descriptions for each "feature" so you know what CM1CON0, etc means. Adobe pages 34-37 are best. Also,
    under the feature headings are listed all relevant registers that need to be set/cleared, usually near the end.

    You might need to set ( or CLEAR) the following registers as well (some required in other PICs):

    'Registers:
    ANSEL = %00000000 ' clears the individual bits that select analog inputs (low register)
    ANSELH = %00000000 ' clears the individual bits that select analog inputs (high register)
    VRCON = %00000000 ' turns the Vref Module OFF by CLEARING bit7, 6, 4

    'I use the binary format so I can easily set them later. I know it seems redundant when they are all 0's, but later....

    'Bits Only:
    CM1CON0.7 = 0 ' turns Comparator1 OFF by CLEARING bit7
    CM2CON0.7 = 0 ' turns Comparator2 OFF by CLEARING bit7
    ADCON0.0 = 0 ' turns the AD Converter OFF by CLEARING bit0
    INTCON.0 = 0 ' clears the RABIF Flag (to 0), COULD be 1 on reset (unique to F690)
    RCSTA.7 = 0 ' clears the SPEN bit ( SETTING SPEN DISABLES RB7 AS GENERAL PURPOSE! )
    'note that there is an Errata Datasheet that mentions issues with SPEN, but only when using the Serial Hardware

    'you might HAVE TO do this after clearing ANSEL/ANSELH
    PORTA = %00000000 ' Clear the port register latches
    PORTB = %00000000
    PORTC = %00000000

    TRISA = %11111111 ' Set or Clear the data direction registers
    TRISB = %11111111
    TRISC = %00000000

    'FOR EXAMPLE: On the F628 and friends, you only need:
    'CM1CON = 7 ' turns the comparators OFF by SETTING bits 0,1,2
    'and the Port/Tris settings

    'OK, now on to your code...
    'The Button Command:
    BUTTON 7, 0, 255, 0, B0, 1, Loop
    '"7" is not a pin name.
    'For buttons and LEDs, I use names like btnStart or btnUp, LEDFault, LEDStatus.
    'But sometime I use PHYSICAL pin numbers on new chips that I'm learning. So try :

    RB7pin10 VAR PortB.7

    'I wouldn't use the term B0 as a variable, it is used so many other places (mainly STAMP) to denote PortB.0. Try:

    Temp VAR BYTE

    'Also, for the Jump To label you use "Loop", but I don't see it in your listing. Maybe you meant "Next", but you can't use that name.
    'So Now:

    Start:
    LED1 = 0

    Button RB7pin10, 0, 255, 0, Temp, 1, Blink

    GOTO Start

    Blink:
    LED1 = 1
    Pause 1000
    GOTO Start
    End

    'I'm not at work so I can't test this until tomorrow.

  20. #20
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit View Post
    BUTTON 7, 0, 255, 0, B0, 1, Loop
    ???????
    Try
    Well, the command & it's example syntax it was lifted from here (page 104)....


    http://books.google.co.uk/books?id=X...sult#PPA104,M1

    I figured that since the button command *only* wokds on PortB, that nominating ust the number 7 (as opposed to RB7) would be ok. certainly the example that link gives justiuses the number 7 too!

    Greg...many thanks for the lengthy reply - i'll give that a shot tonight (I'm at work right now too!)

  21. #21
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    Well, the command & it's example syntax it was lifted from here (page 104)....


    http://books.google.co.uk/books?id=X...sult#PPA104,M1

    I figured that since the button command *only* wokds on PortB, that nominating ust the number 7 (as opposed to RB7) would be ok. certainly the example that link gives justiuses the number 7 too!
    Maybe you should read the manual that came with your copy of PBP. You will see that these book writers do not always know what they are talking about.
    Dave
    Always wear safety glasses while programming.

  22. #22
    Join Date
    Mar 2009
    Location
    San Diego, CA USA
    Posts
    3


    Did you find this post helpful? Yes | No

    Default

    I'm not sure that the Button Command "only works on PortB". Every other command works on any pin except the hardware modules (HPWM, HSERIN, etc).

    Besides you can always use:

    If btnTest = 0 then Blink 'did I change the button name? oops

    Of course there is no debounce, but this is good for testing. Actually, your 1sec delay for the LED is a great debounce! nothing else is going to happen during that interval, nothing. You could also do this to BLINK as long as you hold the button down:

    Start:

    WHILE btnTest = 0
    LED1 = 1
    Pause 500
    LED1 = 0
    Pause 250
    WEND

    GOTO Start

  23. #23
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Greg,

    Just had a chance to try out your suggestions - it works! (iepin 10 is now high...at this stage, I can't be sure which one of those tips you gave was the one that nailed it, becuase I used them all!)

    Some excellent ideas you've given there too about my main program ...in fact, I reckon I've enough sufficient info get this little program sorted now.

    Many thanks to all who took the time to help me out....the internet working at its finest.



    mackrackit...it was very late, & I'd just quickly googled my problem (as I always do when I have a problem & as a beginner, a search engine often serves me better as I can phrase a question when I'm not totally sure of what I'm asking!)...Google led me to that online PICbasic book & I took it at face value!

    Lesson learned.
    Last edited by HankMcSpank; - 16th March 2009 at 18:30.

  24. #24
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Places to get help. for PBP.

    Micro Chip web site for data sheets, other places may not have the current one.
    Melabs web site, can not beat the source for examples.
    rentron.com - Bruce's web site. Very good examples.
    This forum, Darrel has a google search in the FAQ section.

    When you are ready for advanced stuff go to Darrel's web site.

    Any place else and who knows...
    Dave
    Always wear safety glasses while programming.

  25. #25
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    I've just realised that my little program which counts the number of time a switch has been closed (a magnetic switch, which is closed as 10 successive magnets glued to the perimeter of a DC fan motor pass it by!)...isn't counting correctly - & I don't know why (though I suspect it';s either down to the debounce paramters or perhaps the length of time taken to 'do stuff' in between successive magnets).

    here's my simple code (stripped down for clarity)...

    RB7pin10 VAR PortB.7 ;explicity name the switch pin for button command.
    RA3pin4 VAR PortA.4 ;explicity name the switch pin for button command.
    Temp VAR BYTE ; this is used for debounce/delay of the fan switch)
    total_counter VAR WORD ; this will count the total pulses rx'ed from magnets.
    pitch_counter VAR BYTE ; this will utlimately derive the pitch thread (a divider)
    direction_counter VAR word ; this will changed traversal direction word for counts bigger than 255
    pulse VAR PortC.0 ; stepper feed pin 16 (to pin 11 on stepper IC)
    direction var PortC.1 ;direction level pin 15 (to pin 14 on Stepper IC)


    stepper_enable VAR PortC.3 ; Pin 7 this logic level 0 enables the stepper IC (stepper IC Pin 15)

    Start:

    total_counter = 0 ; make sure we start from zero
    direction_counter = 0 ; make sure we start from zero
    direction = 1 ;we want the feed stepper to move left/right first.
    low stepper_enable ;enable the stepper chip.

    Main:
    Button RB7pin10, 0, 255, 0, Temp, 1, magnetic_switch_closed ; monitor the magnetic switch
    goto Main ;if switch not closed, loop until it does close.

    magnetic_switch_closed: ;ok, so switch is now closed - let's count!
    total_counter = total_counter +1 'increment counter to track number of magnets passing switch.
    IF total_counter = 500 THEN
    goto finish ' if using 10 magnets, after 50 turns of the motor exit the program
    endif
    pulse_the_stepper:
    pulsout Pulse, 20 ; pulse the stepper on Port C.0 with 20us pulse.
    Goto main ;return to start & monitor for the switch being closed again

    finish:
    HIGH stepper_enable ;disable the stepper chip
    End




    So to my question....

    Is there a more scientific way to approach this?

    The motor starts off slow, & then increases under manual control up to a speed somewhere between 150RPM & 350RPM. So the rate of magnets passing the switch can be anywhere between 0 per second & 58 passes per second (350/60 = 5.8 turns per second...there are 10 magnets)

  26. #26
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44


    Did you find this post helpful? Yes | No

    Default

    I see a couple of things that make me wonder, your "Temp" Var should be set to 0 at the beggining before you call "Button", if not "Button" won't work correctly.

    Also, you are looking for a switch being closed at rates up to 58 times per second. 1/58 = 17 ms, so ever 17 milli seconds a magnet will sail past your switch, closing it for a moment, then it will re-open. If your magnets cover 50% of the circumference that would give you a 50% duty cycle. So the switch would be closed for 17/2 = 8.5 ms and open for 8.5 ms. In reality, your switch is probably closed about 10 % of the time or 1.7 ms.

    In your code :

    Code:
    Button RB7pin10, 0, 255, 0, Temp, 1, magnetic_switch_closed
    You have delay set at 255, this will perform debounce, but no auto repeat.

    Default debounce is 10 ms, so the switch needs to be closed for 10 ms before you go to "switch_closed"

    You might try a delay of 0, this shuts off the debounce.

    Also you can change the debounce delay:

    DEFINE BUTTON_PAUSE 1 'set button debouce to 1 ms

    1 ms is still cutting it close.

    Or you can skip the button all together and just read the port, something like:

    Code:
    If RB7pin10 = 0 Then switch_closed
    You can read the state of the switch again in the "switch_closed" code, if it's still closed continue, if not jump back out. That performes a high speed debounce. You can also use PAUSEUS before you double check, so you can wait a couple of micro seconds then double check the switch is really closed.

    Just some idea's.

    Shane

  27. #27
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Hi Hank,
    Why not just use count statement, store count in a variable ?
    Looks like you want to find the end of each revolution and then increment the feed over so the wire does not overlap, yes?
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  28. #28
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44


    Did you find this post helpful? Yes | No

    Default

    just another thought on my last post. If you check the state of "magnetic_switch_closed" and jump into you're code where you increment your counter. Before you jump out and look for it being closed again, you should look for it to be open.

    If not then you could count the same swith close multiple times all for the same instance.

    something like:

    Code:
    if RB7pin10 = 1 then main ' make sure the switch opens before looking for another close
    Else stay in loop...
    Shane

  29. #29
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Firstly ....Shane/Joe, thank you for taking the trouble to respond (esp to a basket case of a kludger like me!)

    Ok, to your points...

    Shane you are right about the temp variablle needing to be set to zero...I didn't post up that bit (my program has a lot of variables going on, but I stripped it back to basics so as not to cloud the issue...but I can see it's caused probs!)

    Next....I think you've nailed the issue (my head was fogged last night after realising my program wasn't counting the revs right!)...essentially, my program traps the switch being closed (sort of!), but not the corresponding open. Therefore in reality, my program could see the switch being closed, head off to do some stuff elsewhere in the program, come back to check the switch & by bad luck/timing the next magnet could be passing so it thinks the same (original) magnet is closing the switch. therefore I need to wait for the switch to close, then open, then have my program act.

    Joe... re the counter/variable melarkey - remember, I'm very new to this. I've almost certainly done a tutorial somewhwere & simply applied what I learnt there to my program! (I haven't a lot of time to dedicate to being a slick programmer, so I just throw into the program the little bit that I know!). Could you be so kind as to outline the tighter code for that little increment you've honed in on as being a bit 'first lesson at PICBASIC evening class'!). BTW ...I use this magnet/switch 'count' to derive when to send a pulse to a stepper. This stepper I'm sending the pulse to, moves in synchronicity with the main motor, back & forward (the idea being to neatly feed coppoer wire on to the main turning motor). It's really cool on the odd (seemingly fluke) times I've had it working!

    Shane... the magnets are actually glued around the circumference of a wooden ring (& this ring itself is glued to the fan blades!). The diameter of this ring is about 10cm (4" if you're still in imperial) which makes for a circumference of 31cm ...the magnets themselves are about 1cm wide & there are 10 of them. So the magnets take up a third of the circumference - meaning a duty cycle of 33%?

    Therefore, at a maximum of 350RPM, the magnets will pass by the switch at about 58 times per second. This works out at every 17ms....because of the magnet width, this yields a duty cycle of 33% - therefore the switch will actually be closed for about 5.6ms, every 17ms

    Now my head still spins at the thought of building in the debounce aspect, so
    with these 'knowns' I have, which would be the best approach to ensure an accurate switch 'closing' count?


    (BTW, I'm thinking now that maybe an optical pickup would be a much better solution, as this removes the debounce aspect & I can have more resolution -I will look into this, but for now I'd really like to get the cheap 'n dirty solution working!)

  30. #30
    Join Date
    Apr 2009
    Location
    Boise, Id
    Posts
    44


    Did you find this post helpful? Yes | No

    Default

    Building a debounce isn't too hard, if it's even needed. It just depends on the magnetic switch you are using, if it's solid state you won't need to do much more than check if it's closed, being the way I am, I'd double check it again before actually stepping the moter etc. If it's a mechanical relay, that will need a "real" debounce and maybe some additional external hardware, like a cap.

    To debounce you need a loop that checks if the switch is closed. If it is then increase a debounce var. and check it again, if it's not closed set your debounce var = 0 and keep checking. Determine the amount of time / number if times you want to increase your debounce var. you can put a pauseus 100 and recheck if it's still closed, and when your debounce var = 10 then you know the switch has been closed for at least 1 ms ( 100 us * 10 = 1ms)

    Joe S. had the idea of using count, I've used it and it's simple.

    Code:
    count porta.1, 150 , freqval
    The above code counts the pulses on porta.1 over 150 ms and stores the value in the Var "freqval".

    In your case you would count for 10 ms? something like this:

    Code:
    Counting_Mags:
    count portx.x, 10, mag_count ' count port x pin x for 100 ms
    Num_Mags = Num_Mags + mag_count
    
    if Num_Mags > 9 then One_Rev ' counted at least ten magnets so one revolution has occured, so step motor.
    
    goto Counting_Mags
    
    One_Rev:
    Num_Mags =0 ' reset count
    'do the rest of you stuff here
    
    Goto Counting_Mags ' go back and count another revolution
    Joe S. may have a better idea, and better code for you, above is where I would start, I'm no pro at this myself. I'd use the above code as an example, I just typed it out, so it still needs more work.

  31. #31
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    Joe... re the counter/variable melarkey - remember, I'm very new to this. I've almost certainly done a tutorial somewhwere & simply applied what I learnt there to my program! (I haven't a lot of time to dedicate to being a<b> slick programmer</b>, so I just throw into the program the little bit that I know!). Could you be so kind as to outline the tighter code for that little increment you've honed in on as being a bit 'first lesson at PICBASIC evening class'!). BTW ...I use this magnet/switch 'count' to derive when to send a pulse to a stepper. This stepper I'm sending the pulse to, moves in synchronicity with the main motor, back & forward (the idea being to neatly feed coppoer wire on to the main turning motor). It's really cool on the odd (seemingly fluke) times I've had it working!
    <b>HA HA HA, ME EITHER !</b> I wrote a Tachometer program, using count, look it over as an exemplar of using count. The code is in post #9. http://www.picbasic.co.uk/forum/showthread.php?t=9037

    Quote Originally Posted by HankMcSpank View Post
    Now my head still spins at the thought of building in the debounce aspect, so
    with these 'knowns' I have, which would be the best approach to ensure an accurate switch 'closing' count?


    (BTW, I'm thinking now that maybe an optical pickup would be a much better solution, as this removes the debounce aspect & I can have more resolution -I will look into this, but for now I'd really like to get the cheap 'n dirty solution working!)
    Optical can be cheap and reliable, magnetic is good too, thinking hall effect switch. Do you really need 36 degree resolution (10 magnets)? Using an interrupt might be your solution to all this. I do not think I would use a magneto mechanical (reed) switch as a pickup, but using a hall effect would free you of all that debounce nonsense. Sam used my code with 1 magnet for his Tach. and says it works well. As for optical, tear open an old mouse and you will find a PIC and 2 optical pickups using shutter wheels. People use printed encoders for tabletop robots all the time. A coil of wire, magnets, and a comparator input will work too, that is what works most auto ignitions, in fact I used an old car distributor while working out my tach. code. A 555 timer can be used as a wave shaper if you are not ready to try comparators yet.
    Last edited by Archangel; - 28th April 2009 at 17:20.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  32. #32
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Joes' idea for the hall effect sensor would be the way to go. Then you could simplify the
    whole thing with a timer configured to count external pulses. Preload the timer to over
    flow after 500 ticks, and have an interrupt flip the port pin to kill the motor.

    The timer counts in the background, so you can have all sorts of other things happening,
    code wise in the meantime. And with zero code for counting pulses.

    If you prefer to sit & spin in a loop until killing the motor, you could just monitor the timer
    overflow bit, and not use any interrupts.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  33. #33
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Alas, my existing switch setup is a simple reed switch (so I have to debounce).

    I've done some googling today & think that optical is the way to go. I'll probably use this guys implementation - a CD with some black stripes drawn on it!

    http://www.vk2zay.net/article/29

    http://www.vk2zay.net/article/28

    (but perhaps having it feed into a monostable to clean those pulses up a bit)

    Firstly, it appeals to the cheapskate in me, but more importantly, I can get even finer resolution - surprisingly 36 degree resolution isn't really sufficient...I'd much rather have 10 degrees or less

    Totally off topic, but here's the maths.

    Let's I'm feeding 0.15mm wire onto the main motor (actually the main motor holds a steel rod in jaws, upon which the copper wire feeds onto forming a coil)

    So, for every turn of the main motor, I need the stepper motor (feeding the wire onto it), to traverse by 0.15mm.

    My stepper is a 7.5 deg motor (meaning it takes 48 pulses to get it to turn one full revolution). I've placed some M8 threaded rod over the stepper shaft (this has a pitch of 1.5mm)....it is via this thread that I wrap the copper wire around feeding onto the main motor, if you can't visualize this...have a look here for a similar setup about 23 seconds in...he's using *much* chunkier wire, mine is more akin to thick hair).

    Therefore for every full turn of the stepper (48 pulses) the wire moves 1.5mm (this being the thread pitch). But I *need* it to move just 0.15mm for every turn of the main motor. So to get the stepper to move the wire just 0.15mm, I need to send 4.8 pulses to the stepper for every turn of the main motor - obviously, I can't send 0.8 of a pulse to the stepper! Therefore if I had more tach resolution, I'd avoid such 'rounding' errors (or as I'm doing now, having to add in extra pulses every so often to make up for the shortfall)
    Last edited by HankMcSpank; - 28th April 2009 at 19:17.

  34. #34
    Join Date
    Aug 2006
    Location
    Look, behind you.
    Posts
    2,818


    Did you find this post helpful? Yes | No

    Default

    Hi Hank,
    48 steps per rev, wow most steppers are 200 steps per rev. Saw the video. 1 Q & D way to get resolution in accurate form, Order from your local speed shop a degree wheel for setting cam timing, has 360 degrees embossed on an 8 inch aluminum disc. you can drill holes at exact spacing or use it as a protractor to make other discs.
    If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
    .
    Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
    .
    There simply is no "Happy Spam" If you do it you will disappear from this forum.

  35. #35
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi Joe,

    Thanks for the top tip re the disc (I'll ponder that one!)

    Re my program....well I got it working last night, here's what I did...

    (Note as you read below, you need to know the incoming magnetoic switch is connected to PORTB.7 & the default condition is High...when the switch is closed it goes low)

    Main:
    If portb.7 = 0 then 'if low, then a magnet's leading edge has just past the switch
    mag_start = 1 ' therefore set a variable condition to reflect this
    Pause 3 ' pause a little to ensure we don't check the switch while it's bouncing
    goto next1 ' if we have the mag leading edge, go to the next bit
    endif
    goto main ' keep looping until we do get a leading edge

    next1:
    If portb.7 = 1 then ''if high, then a magnet's trailing edge has just past the switch
    mag_end = 1 ' therefore set a variable condition to reflect this
    endif
    If mag_start = 1 and mag_end = 1 then ' if both conditions are met, then we've just had one magnet pass
    Goto one_magnet_passed
    endif

    one_magnet_passed:
    mag_start = 0 'reset this puppy, ready for next time
    mag_end = 0 ' ditto
    Num_Mags = Num_Mags + 1 ' count number of magnets that have passed
    if Num_Mags > 9 then one_rev ' counted at least ten magnets so one revolution has occured, so go do 'stuff'

    one_rev:
    Num_Mags = 0
    pulsout PortC.0, 10 ; pulse the stepper

    blah, blah.


    The benefit of doing it in the above manner (I'm sure there are better ways, but hey...it works for me!), is that it'll work at virtual 'stop' speed, right on up to about 400RPM.

    I went all low tech & taped a lump to the edge of the motor, so I could feel/count revs with my finger as the lump passed. I also used debug to put the rev count onscreen to make sure it concurred with my manual count - it was bang on.


    Many thanks for all your help!



    PS Joe, yes, 7.5deg steppers are somewhat unusual, it was a 'form feed' motor taken out of an old dot matrix printer...it's actually ideal for this job...I doubt I'll ever need more than 48 steps resolution per RPM for the wire types I'm winding. It's also a very light motor, therefore draws little power & is virtually silent. If I get a moment I'll post up a youtube video of what my setup is (warning - it's very kludgy. & lo-tech & ugly...but it does the job!)
    Last edited by HankMcSpank; - 29th April 2009 at 13:10.

  36. #36
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Hi - me again!

    Ok, I think I mentioned that I was going to bin my 'magnets & reed switch'...in favour of an optical pickup (I needed more 'resolution' & less debouncing) - well, I have all the pieces in place now...so why am I back?

    well, I need help wrt how I can be sure to ascertain that my circuit (& program) is actually picking up all the pulses fine. And with a motor turning at between 300 & 400RPM, and 48 stripes per revolution...I lose count when doing this manually!

    Here's the circuit I've implemented.... http://hans-w.com/RPM.gif (I should point out that Im not using the same PIC - I'm using a 16F690 - nor his hex code...as I need to be able to customize the program)

    Re the tach pickup itself - on the edge of my turning motor is a phototransistor aimed at a round disc with 48 lines on it (essentially a pie chart knocked up in Excel, printed onto a CD label & then onto an old CD!!) ...as each one of these lines passes the phototransistor, a pulse ultimately appears at a PIC input pin.

    It seems to be working reasonably well *but* I have a sneaking suspiscion, that either the electronics is not setup right (there's a preset in that schematic that needs setting optimally - I have a scope, but at 48 pulses per rev running at 400RPM, the trace is too jittery to set the levels in this manner).

    What I'd like to know, is the best way to establish that *all* 48 stripes are being 'seen' by the PIC and everyrevolution (not just for one revolution, but say over 400 revolutions).

    I'm figuring it'll need some form of counter, with the methodology being something along these lines (this is a labourious method!)....

    Start counter
    Pulse 1 arrives - output this info to screen along with counter time (I'm using the Pickit2 Uart tool to debug)
    Pulse 2 arrives - output this data to screen along with counter time.

    I can then cut/paste the above into Excel, do a bit of simple maths (ie subtract each 'counter time' from the previous, which will yield the time taken beteween successive pulses) & ultimately put this into a bar chart. All being well my bar chart should have bars of equal height from left to right.

    Since the above method seems a bit long winded, I'm sure there must me a slicker way in real time, for example...

    Start counter
    Pulse 1 arrives - note the time in variable1
    pulse 2 arrives - note the time in variable2
    Subtract variable 1 from variable 2 (to give the time between pulses) - place into variable 3

    then continue in a similar vein?

    The clever bit would be to have a calculation that goes along the lines of "If the time between successive pulses is greater than say 90%, then we must have missed a pulse - output this info to screen via the Pickit Uart tool.

    Does this sound plausible?

    Could anyone help me out with a little bit of code to get me started please?(I've never dealt with counters previously!)
    Last edited by HankMcSpank; - 16th May 2009 at 15:36.

  37. #37
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok...first sign of madness is talking to yourself - I must be totally barking.

    Tonight, I knocked up an encoder wheel & used DT's interupt utility to assist the PIC in cleanly counting the 96 black stripes ...using interupts vs polling is a great success (ie I reckon all the black lines are being counted now).

    But I've a new problem!

    Previously, I have been using the Microchip Uart tool to output the number of encoder revs counted by the PIC onto my PC screen (essentially I just output a dedicated variable that increments after every 96 black stripes have been counted).

    Up until now, everything was fine - could see my info onscreen quite fine.

    My problem now is that becuase the black stripe interupts are running every 2ms (this number being based on a speed of 300RPM - which equates to 5 revs per second... therefore 200ms divided by 96 'black stripes' = 2.08ms between interupts) ...my onscreen info has become truncated/garbled. If I slow the wheel speed right down to say about 30RPM...it's fine....I can read my revs on my PC screen again.

    this suggests that the interupts are interfering with the serial comms/Debug/Uart signal flow. (this is a little puzzling as I had thought the whole point of interupts was to be non disruptive in the sense they tuck everything away before heading off to do the interupt routine, & then pick up where they left off by 'restoring things as they were' after the routine?)

    Does anyone have a cunning plan to allow me to get my simple onscreen Debug info back - I only need to see one small bit of info...this being the total rev count in pseudo real time onscreen. (I'm happy to consider alternatives too?!)
    Last edited by HankMcSpank; - 20th May 2009 at 01:53.

  38. #38
    Join Date
    Mar 2006
    Location
    China
    Posts
    266


    Did you find this post helpful? Yes | No

    Default 16f690 right?

    Hi,

    If you have a look at RB7 it is also called TX. This is the HARDWARE port for the serial communication. HSEROUT or HSEROUT2 will be the tool for this :-)

    When you use the hardware serial port you only need to put a byte in the transmit buffer and then the PIC will send out the 10 bits for you with proper timing (start bit, 8 data, stop bit) so the interupts will not trash your data.

    /me

  39. #39
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Thanks for your input.

    I'm struggling a little with the options available to get variable 'contents' to the outside world! Here's my understanding (though could be worng!)...

    1. Hardware serial .... the traditional manner (neds a converter such as a MAX232). I'd like to keep it simple & component count low as possible, so I'm not pursuing this route.

    2, PICKit2 - Uart tool....this is what I'm using at the moment, but like I say,the high number of interupts is causing havoc with the data I'm seeing onscreen..

    Now this is where it gets a little 'grey' for me ....I'm using the command "Debug" to get my variable contents out and onto my PC via the Pickit2 Uart tool... I'm not calling any special .bas files - it just works! Is this using software or hardware?

    Now then, I'm just reading on this page...

    http://www.electro-tech-online.com/m...t-example.html

    where the guy declares in one of his headers...

    Device = 18F4550
    Clock = 8
    Config FOSC = INTOSCIO_EC

    // import usart module...
    Include "usart.bas"


    I'm figuring that going this route might actually use the PIC uart hardware? If so, this sounds ideal....can anyone shed any light here please?

  40. #40
    Join Date
    Mar 2006
    Location
    China
    Posts
    266


    Did you find this post helpful? Yes | No

    Default Probably nooot

    Some of the new 18-series PIC has the possibility to invert the hardware usart using a register setting. Your pic does not have that option..

    just remember that sometimes people take component count and simplicity too far and they end up complicated and miserable. Sometimes a MAX can help... especially if you find one that requires zero external components :-)

Similar Threads

  1. Melabs U2 Programmer Command Line Options
    By Robert Wells in forum General
    Replies: 5
    Last Post: - 3rd July 2009, 02:11
  2. problems with USB programmer
    By malc-c in forum General
    Replies: 7
    Last Post: - 10th May 2007, 20:14
  3. USB programmer problems
    By uiucee2003 in forum USB
    Replies: 2
    Last Post: - 15th August 2006, 23:47
  4. General Programmer Questions
    By mslaney in forum General
    Replies: 1
    Last Post: - 17th December 2004, 18:16

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts