+ Post New Thread
Results 1 to 9 of 9
  1. #1
    Newbie level 4
    Points: 1,736, Level: 9
    Achievements:
    7 years registered

    Join Date
    Sep 2010
    Posts
    6
    Helped
    0 / 0
    Points
    1,736
    Level
    9

    I wrote simple code buttons to rotary for PIC12F509, but it works only on simulation!

    Hello! I tried to write my own code for 2 push buttons to rotary encoder (UP/DOWN Quadrature generator)
    I have flashed it (ofcourse with changed ports) on PIC16F648 and it works perfect, it also works perfect in Proteus simulation with PIC12C509 (C509 was the closest i have to F509).

    The problem comes when i program it on real PIC12F509 - the chip doing NOTHING but when i press reset it resets (i put 2 leds on outputs and they flicker on reset)!

    GP0 = UP - button used with pull down
    GP1 = DN - button used with pull down
    GP2 = not connected/set to output
    GP3 = RESET trough pullup 10k to Vcc and button to GND
    GP4 = OUT B - output 2 - connected LED through 220 ohm to GND
    GP5 = OUT A - output 1 - connected LED through 220 ohm to GND

    The outputs just stay high and no reaction!
    What i am doing wrong? I struggle with it for 3 days now and nothing work on real chip (i have few of them brand new)

    MPLAB IDE 8.30 with High-Tech C compile it (for F509) with no errors.
    The fuses are configured outside of the code - IntOSC, CP - OFF, RESET - ON, WDT - OFF

    My Programmer is PicKit3 and also flash it perfectly!

    It just does not work on real chip.
    Please help me if anyone can.

    Here is the
    Code:
    /*
    PIC12F509 buttons to
    rotary encoder truth table.
    ===========================
    Count UP   OUTA  OUTB
    ===========================
    <1.1> =     H  -  H
    <1.2> =     L  -  H
    <2.1> =     L  -  L
    <2.2> =     H  -  L
    ===========================
    Count DN   OUTA  OUTB
    ===========================
    <1.1> =     H  -  H
    <1.2> =     H  -  L
    <2.1> =     L  -  L
    <2.2> =     L  -  H
    ===========================
    */
    #include 
    
    #if defined(_12F509)
      __CONFIG(0x31FA); 
    #endif
    
    //define buttons
    #define UP GP0
    #define DN GP1
    unsigned int j;
    // 8  = number of loop iterations for 1 ms at 4 MHz
    #define loop4_ms 8
    
    //functions 
    void pause_ms(unsigned int given_ms);               // pause for given_ms milli seconds
    //end functions
    int REP;        //Repeat cycle 'n' times
    
    unsigned char const STEPS_MAP[4] = {0b111000,0b011000,0b001000,0b100100};
    int step=0;
    
    //main code
    void main(void) {    
    #if defined(_12F509)
        TRIS = 0b001011;          // Set GP4,GP5 as outputs & GP3, GP0, GP1 as input (0 => Output, 1 => input)
    #endif
        GPIO   = 0b001000;        // Set GPIO = 0 for all output but 1 for GP3/MCLR input
    	OPTION = 0b11010000;    
    do
         {
             if (UP)            //Check if switch  is closed
               {
                 pause_ms(90);   //wait for 90ms  (switch debouncing)
                 if (UP)         //Check if switch is still closed
                    {
                     for(REP=0; REP<=1; REP++)        //Repeat steps until 'n'
       				{
       				 GPIO = (STEPS_MAP[step]);     //Load current state
     			   	 pause_ms(250);                  //Pulse time
        			 step++;                        //Count +
        			 if (step>3)step=0;
    
       				}
        			 REP;                //End REP
    
                    }
               }
    
              else
                 {
                     GPIO = (STEPS_MAP[step]);
                 }
              if (DN)            //Check if switch  is closed
               {
                 pause_ms(90);   //wait for 90ms  (switch debouncing)
                 if (DN)         //Check if switch is still closed
                    {
                      for(REP=0; REP<=1; REP++)
      				{
        			  GPIO = (STEPS_MAP[step]);     //Load current state
        			  pause_ms(250);                  //Pulse time
       				  step--;                        //Count -
       				  if (step<0)step=3;
        			}
          			  REP;                //End REP
                    }
               }
              else
                 {
                     GPIO = (STEPS_MAP[step]);
                 }
                  
         }
    
    	while(1);
    }
    //end main code
    
    	void pause_ms( unsigned int given_ms ) {  // pause for given_ms milli seconds
        
    	unsigned long j, max_time = given_ms * loop4_ms;
        for(j=0; j < max_time; j++);          // Make waiting for about given_ms msec
    };
    And schematic:

    Click image for larger version. 

Name:	F509_B_rot.jpg 
Views:	11 
Size:	104.7 KB 
ID:	156856

    •   AltAdvertisement

        
       

  2. #2
    Advanced Member level 3
    Points: 3,492, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    700
    Helped
    51 / 51
    Points
    3,492
    Level
    13

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    Here is a code that you can use with a little modification according to your PIC.

    Code:
    // Value changes up or down as encoder is turned.
    // encoder 2 outputs are PORTB.F1 and PORTB.F0
    // logic; if newA == oldB, encoder turned clockwise
    // if newA != oldB, encoder turned counterclockwise
    // example; (AB) 00 01 11 10 00 01 11 10 00
    
    char value;
    char new_encoder;
    char last_encoder;
    
       new_encoder = (PORTB & 0x03);      // keep only 2 bits
       if(new_encoder != last_encoder)      // if encoder has changed
       {
          if(new_encoder.F1 == last_encoder.F0) value++;
          else value--;
    
          last_encoder = new_encoder;   // save for next time
       }
    There should be no blocking delays or if your PIC supports external interrupts on at least one pin then you can use that feature and put the whole code in the external interrupt ISR.



  3. #3
    Newbie level 4
    Points: 1,736, Level: 9
    Achievements:
    7 years registered

    Join Date
    Sep 2010
    Posts
    6
    Helped
    0 / 0
    Points
    1,736
    Level
    9

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    baileychic, than you for replay. It is not rotary encoder to UP and Down commands (logic states), it is the opposite UP and DOWN buttons to two way quadrature generator function (rotary encoder) in other words - replace encoder with buttons.
    My programming skills are poor but that is not what i need and as i said it is for PIC12F509 - this exact code work on real PIC16F648 and in proteus sim for PIC12C509 but it compiles to PIC12F509 flawlessly and is dead on real pic12.... I also have build the whole thing out of CMOS logic and also works, but i wanted something compact and simple. I also want to learn where is my mistakes to improove myself



  4. #4
    Advanced Member level 3
    Points: 3,492, Level: 13
    baileychic's Avatar
    Join Date
    Aug 2017
    Posts
    700
    Helped
    51 / 51
    Points
    3,492
    Level
    13

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    Show your actual hardware encode and provide its datasheet.



    •   AltAdvertisement

        
       

  5. #5
    Super Moderator
    Points: 29,994, Level: 42
    andre_teprom's Avatar
    Join Date
    Nov 2006
    Location
    Brazil
    Posts
    8,947
    Helped
    1134 / 1134
    Points
    29,994
    Level
    42
    Blog Entries
    9

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    As said above, your code have a lot of blocking instructions that blinds the program for a while preventing from reading the actual encoder, for which we should just guess it have a resolution of houndred or thousands pulses per cycle (you did not mention anything about its specifications, nor rotation speed). On simulation everything works fine even when programming with inappropriate approaches. You should consider using I/O interrupt feature.

    Another point to remark is that your encoder MAP do not handles abnormal execution, e.g whether a missing pulses happened or not, which is expected when the axis turns faster than your code can deal with; you could provide an output LED just to inform such an situation.
    --------------------------------------------------------------------------------------------------
    Part of the world that you live in, You are the part that you're giving ( Renaissance )



  6. #6
    Newbie level 4
    Points: 1,736, Level: 9
    Achievements:
    7 years registered

    Join Date
    Sep 2010
    Posts
    6
    Helped
    0 / 0
    Points
    1,736
    Level
    9

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    andre_teprom, thank you for your reply. I am not trying to READ Rotary Encoder but to emulate its function with buttons and replace it. LED1 and LED2 are there only to test and indicate outputs states, they won't be connected on finished board.

    baileychic, The hardware is exact copy of the schematic i provided in the first post.

    Click image for larger version. 

Name:	IMG_20191214_104625.jpg 
Views:	7 
Size:	521.5 KB 
ID:	156901

    The function, I'm trying to create is:
    Code:
    loop4_ms=8  -> represent 1mS delay, for 4MHz internal oscillator is 8 MCU cycles
    
    STEPS_MAP should represent the corresponding output LEDs AB -> 11 01 00 10
    first initialize on step0 (e.g. 11)
    
    if button UP = 1 for more than 90mS and less than 250mS -> count UP two steps from current steps state from STEPS_MAP
    e.g. -> step0 wait 90mS step1 wait for 250mS -> and stay on current step
    
    when button UP is holded for more than 250mS -> do two more steps or just continue to count untill the button is pressed 
    e.g. -> step0 -> wait 90mS step1 -> wait for 250mS -> step2 -> wait for 90mS -> step3 -> wait for 250mS -> step0 ... and so on (0,1,2,3,0,1, ...)
    
    and when button is released stay on current step
    when pressed again continue from current step 
    
    if button DN = 1 for more than 90mS and less than 250mS -> count DN two steps from STEPS_MAP
    e.g. -> step0 wait 90mS step1 wait for 250mS -> and stay on current step
    
    when button DN is holded for more than 250mS -> do two more steps or just continue to count untill the button is pressed 
    e.g. -> step3 -> wait 90mS step2 -> wait for 250mS -> step1 -> wait for 90mS -> step0 -> wait for 250mS -> step3 ... and so on (3,2,1,0,3,2, ...)
    
    and when button is released stay on current step
    when pressed again continue from current step
    
    Everytime when any of 2 buttons is pressed always count from current step NOT from begining of STEPS_MAP
    Here is the quadrature simulation of single push (showing UP press, for DN is the exact opposite way):
    Click image for larger version. 

Name:	UP_func.jpg 
Views:	7 
Size:	450.5 KB 
ID:	156900

    Here is the quadrature simulation of holding UP and DN:
    Click image for larger version. 

Name:	UP_DN_HOLD.jpg 
Views:	7 
Size:	402.3 KB 
ID:	156899

    You can clearly see the "TETRIS fugure" is perfectly mirrored on the counting down sequence in the second image.

    the STEPS_MAP table was in 8-bit hex values but i translate it to binary format so i can easily change the order of bits and see what i have.
    If i could find sample for blinking led with delays and mapping the GPIO port as byte word for PIC12F509, i think i will be able to manage the code. I don't know how to write code for interrupts and how to enable internal hardware and use it and i thought that GPIO command can be exequted as PORTA on PIC16 ... and i stuck. PIC12F509 just doesn't want to work exept in simulation i can see it is alive when i reset it and that is all it does, and i have few of them, both do exately the same and they are brand new.

    I atached the whole project to check it. It uses Proteus 7.10 and MPLAB IDE 8.30
    I hope i provided the whole information about my problem!



  7. #7
    Newbie level 4
    Points: 1,736, Level: 9
    Achievements:
    7 years registered

    Join Date
    Sep 2010
    Posts
    6
    Helped
    0 / 0
    Points
    1,736
    Level
    9

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    If someone can write this function in any language please!
    I edited the code, but even this doesn't work on real chip:
    Code:
    /*
    PIC12F509 buttons to
    rotary encoder truth table.
    ===========================
    Count UP   OUTA  OUTB
    ===========================
    <1.1> =     H  -  H
    <1.2> =     L  -  H
    <2.1> =     L  -  L
    <2.2> =     H  -  L
    ===========================
    Count DN   OUTA  OUTB
    ===========================
    <1.1> =     H  -  H
    <1.2> =     H  -  L
    <2.1> =     L  -  L
    <2.2> =     L  -  H
    ===========================
    */
    // CONFIG
    #include 
    __CONFIG(0x0FEA);
    //__OSCCAL(0x0C3A);
    #define _XTAL_FREQ 4000000
    #include 
    #define UP GPIObits.GP5
    #define DN GPIObits.GP4
    
    /*#define loop4_ms 8  // 8 is number of loop iterations for 1 ms at 4 MHz
    
    //**********functions****************
    
    unsigned int j;
    
    void pause_ms(unsigned int given_ms);               // pause_ms(n); function same as delay_ms(n); 
    
    //**********mapping steps************
    
    unsigned char const STEPS_MAP[4] = {0b11,0b10,0b00,0b01};
    int step=0;
    */
    //main code
    void main(void) {    
        TRIS   = 0b110000;          // Set GP0,GP1,GP2 as outputs & GP3, GP5, GP4 as input (0 => Output, 1 => input)
        GPIO   = 0b000000;        // Set GPIO = 0 for all outputs
    	OPTION = 0b11000000;      //Set functions for MCU pins - 0x30
    
    GP0=1; //I LEAVE ONLY THIS AND EVEN THIS DOES NOT WORK!
    /*	    
    do
         {
             if (UP)            //Check if switch  is closed
               {
                 pause_ms(90);   //wait for 90ms  (switch debouncing)
                 if (UP)         //Check if switch is still closed
                    {
       				 GPIO = (STEPS_MAP[step]);     //Load current state
     			   	 pause_ms(250);                  //Pulse time
        			 step++;                        //Count +
        			 if (step>3)step=0;				
    				}
               }
    
              else
                 {
                     GPIO = (STEPS_MAP[step]);
                 }
              if (DN)            //Check if switch  is closed
               {
                 pause_ms(90);   //wait for 90ms  (switch debouncing)
                 if (DN)         //Check if switch is still closed
                    {
      				  GPIO = (STEPS_MAP[step]);     //Load current state
        			  pause_ms(250);                  //Pulse time
       				  step--;                        //Count -
       				  if (step<0)step=3;
       				}
                }
              else
                 {
                     GPIO = (STEPS_MAP[step]);
                 }
         }
    */
    	while(1);
    
    //}
    //end main code
    /*
    	void pause_ms( unsigned int given_ms ) {  // pause for given_ms milli seconds
        
    	unsigned long j, max_time = given_ms * loop4_ms;
        for(j=0; j < max_time; j++);          // Make waiting for about given_ms msec
    */
    };



    •   AltAdvertisement

        
       

  8. #8
    Super Moderator
    Points: 82,632, Level: 70
    Achievements:
    7 years registered
    Awards:
    2nd Helpful Member
    betwixt's Avatar
    Join Date
    Jul 2009
    Location
    Aberdyfi, West Wales, UK
    Posts
    13,571
    Helped
    4516 / 4516
    Points
    82,632
    Level
    70

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    Check the pull-up settings in the OPTION register. They may be fighting against the pull-down resistors in the actual product.

    Brian.
    PLEASE - no friends requests or private emails, I simply don't have time to reply to them all.
    It's better to share your questions and answers on Edaboard so we can all benefit from each others experiences.



  9. #9
    Newbie level 4
    Points: 1,736, Level: 9
    Achievements:
    7 years registered

    Join Date
    Sep 2010
    Posts
    6
    Helped
    0 / 0
    Points
    1,736
    Level
    9

    Re: I wrote simple code buttons to rotary for PIC12F509, but it works only on simulat

    Problem is solved in another forum, it was the CONFIG register settings.
    Anyway thanks to all who tryed to help.

    The thread may be closed now.



--[[ ]]--