Voltage output from PIC16f628A


Closed Thread
Results 1 to 15 of 15
  1. #1
    bennamanna's Avatar
    bennamanna Guest

    Question Voltage output from PIC16f628A

    Hi all,

    I am very new to pics and programming. I have a PIC16f628A of which I want to use for a project. I wish to have 2 voltage outputs. One 0-2.5v and the other 0-5v. I wish to be able to to send commands from a PC via rs232 to set these voltages. I am using picbasic for the project. Can anyone give me some guidance or some code of a similar project that I can learn from? The pc coding is fine. I am using VB and comm control.

    Thanks,

    Ben

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Tons of different way

    Scheme 1:
    Use HPWM to produce your 0-5 volt
    Use a op-amp and use the Vref signal to produce you 2nd 0-2.5 volt. If you can deal with the resolution.. it works.

    Scheme2:
    Use HPWM for your 0-5 volt
    Create a timer based PWM to create the second PWM channel

    Scheme3:
    Use 2 DAC. MAX437 is simple and cheap

    Scheme4:
    Use Darrel Taylor Multi SSPWM. So you may produce few different voltage output.

    Scheme5:
    Create you own multi PWM output based on Timer interrupts.

    Scheme6:
    Use a PIC with 2 CCP module.. hence two PWM output. 16F876,16F877 and the list is long enough to fill the screen here

    Scheme7:
    Use 2 PIC with 1 PWM. 1XPIC16F628 + PIC 12F683 talking together.

    There's some others but it should be enough to start?
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Default Voltage

    Gday,

    Thanks for your reply. I am testing some of your methods. I have a few queries.

    1. This voltage i require is to be read by a vehicle ecu. If you use PWM will it see that as a voltage or will it see the pulses?

    2. I have put together some code to test the PWM output. It is giving a PWM signal as expected but when I input a figure in a terminal it does not put the same figure to the display or PWM output. It does change but not as expected. Any ideas why?

    Thanks


    INCLUDE "modedefs.bas" ' Include serial modes
    SI VAR PORTB.1 ' Serial Input pin
    B0 VAR BYTE
    Define OSC 10

    Define LCD_DREG PORTA ' RA0..3
    Define LCD_DBIT 0
    Define LCD_RSREG PORTA ' RA6
    Define LCD_RSBIT 6
    Define LCD_EREG PORTA ' RA4
    Define LCD_EBIT 4
    Define LCD_BITS 4
    TRISA = 0
    TRISB = 0
    CMCON = 7

    Pause 1000 ' Wait for LCD to startup



    duty VAR WORD ' Duty cycle value (CCPR3L:CCP3CON<5:4>)


    TRISB.3 = 0 ' Set PORTB.5 (CCP3) to output
    CCP1CON = %00001100 ' Set CCP3 to PWM
    T2CON = %00010101 ' Turn on Timer2, Prescale=4

    ' Use formula to determine PR2 value for a 1KHz signal,
    ' 4MHz clock, and prescale=4. (4E6/(4*4*1E3))-1=249

    PR2 = 249 ' Set PR2 to get 1KHz out

    ' Use formula to determine CCPR3L:CCP3CON<5:4> value for
    ' ends of range 20% to 80%. (249+1)*4*0.2=200 (20% value)
    ' (249+1)*4*0.8=800 (80% value)


    duty = 200 ' Set duty cycle to 20%

    loop: SerIn SI,T9600,duty
    CCP1CON.4 = duty.0 ' Store duty to registers as
    CCP1CON.5 = duty.1 ' a 10-bit word
    CCPR1L = duty >> 2

    'duty = duty + 5 ' Increase duty cycle
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut # duty ' Display line 1
    pause 1000
    ' Since the total sweep of duty is 600 (800-200) and
    ' we are adding 10 for each loop, that results in 60
    ' steps min to max. 1 second divided by 60 = 16.67mS

    Pause 17 ' Pause 1/60 of second

    'IF (duty < 900) Then loop ' Do it again unless 80% duty cycle

    'duty = 200 ' Reset to 20% duty cycle

    GoTo loop ' Do it forever

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    your CCP definition are fine for 4MHZ, but not for 10MHZ.

    download this tool bellow
    http://www.picbasic.co.uk/forum/showthread.php?t=4994

    it will give you some answer.

    1. This voltage i require is to be read by a vehicle ecu. If you use PWM will it see that as a voltage or will it see the pulses?
    More than likely it will see pulses. You have to convert it to pure DC with a simple RC filter... better if you add a op-amp buffer in between.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Smile Voltage

    Gday,

    Thanks again for your reply. I will use a rc filter as you suggested.

    I have downloaded your calc. It looks like it would be verry usefull. As stated I am a beginner ;- ( Could you please step me through what I have to enter in to your calc and my code to fix it? I will learn this way.

    Thanks,

    Ben

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    you just need to enter the OSC speed and expected frequency. it will give you...
    <img src="http://www.picbasic.co.uk/forum/attachment.php?attachmentid=1168&stc=1&d=116295770 1">
    There, you have the
    prescaller => 1:16 => see T2CON setting in your datasheet
    PR2 => 155 => directly

    It also give you the value for 100% duty cycle => 625

    If you want to set different DutyCycle, move the scroll bar at the top right. The duty value will be reported in the 'results' section at the bottom.

    Not much.
    Attached Images Attached Images  
    Last edited by mister_e; - 8th November 2006 at 03:55.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  7. #7
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Smile

    Gday again,

    Thanks for that info. I changed the PR2 as per your calculation. It still does not seem to give the same value as I enter in the terminal application. If I am correct in my coding, if I send it 100 with a terminal app 100 should display on the LCD and it should set the duty cycle to 100. This is not the case. It says 34 on the LCD and reflects that in the duty cycle.

    Any ideas?

    Thanks,

    Ben

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    I don't know wich terminal software you're using but be sure it send ASCII character and use the right modifier in your Serin/Serin2/DEBUGIN/HSERIN line.

    Look for # or DEC.

    Also, make sure your terminal software don't send cr and lf character.

    Once you're sure of it, you should have better results.

    If you send 100 and receive it correctly, you should have a 16% duty cycle.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Smile

    Gday,

    I am using serial communicator that is with microcode studio. I cant see a setting to ensure it is sending ascii. I made sure it was not sending cr and it made no diference.

    The code I am using is below.

    NCLUDE "modedefs.bas" ' Include serial modes
    SI VAR PORTB.1 ' Serial Input pin
    B0 VAR BYTE
    Define OSC 10

    Define LCD_DREG PORTA ' RA0..3
    Define LCD_DBIT 0
    Define LCD_RSREG PORTA ' RA6
    Define LCD_RSBIT 6
    Define LCD_EREG PORTA ' RA4
    Define LCD_EBIT 4
    Define LCD_BITS 4
    TRISA = 0
    TRISB = 0
    CMCON = 7

    Pause 1000 ' Wait for LCD to startup

    duty VAR BYTE ' Duty cycle value (CCPR3L:CCP3CON<5:4>)

    TRISB.3 = 0 ' Set PORTB.5 (CCP3) to output
    CCP1CON = %00001100 ' Set CCP3 to PWM
    T2CON = %00010101 ' Turn on Timer2, Prescale=4

    PR2 = 155 ' Set PR2 to get 1KHz out
    duty = 100 ' Set duty cycle to 20%

    loop:
    SerIn SI,T9600,,duty
    if duty > 625 then
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "Duty to great" ' Display line 1
    goto loop
    endif

    CCP1CON.4 = duty.0 ' Store duty to registers as
    CCP1CON.5 = duty.1 ' a 10-bit word
    CCPR1L = duty >> 2

    'duty = duty + 5 ' Increase duty cycle
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut # duty ' Display line 1

    GoTo loop ' Do it forever

    Any other ideas why it is not receiving the same as I send it?

    Thanks,

    Ben

  10. #10
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    hi Ben,

    Since our PICs are serial processors, at least for now, and must execute the instructions serially, that is to say one line or instruction at a time, you will never get Serin and Serout commands working at the same time.

    If you use hardware USART, then it will be working in the background, so that you can receive something at the same time you send it.


    -----------------------------
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  11. #11
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    As i said before... look for # modifier... it convert your ASCII string to a DECIMAL value.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  12. #12
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Smile

    Hi sayzer,

    Thanks for your reply. I did not think that my code was trying to use ser in and out at the same time? Could you indicate where I am doing this? Thanks mate.

    mister_e,

    Thanks once again. I'm sorry if I'm making you repeat your self. As stated before I am a beginner. I had however already played with # in my code. I tested it with and without. With out # all i get is jargon.

    Thanks,

    Ben

  13. #13
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Code:
    T2CON = %00010101 ' Turn on Timer2, Prescale=4
    '
    '
    '
    duty = 100 ' Set duty cycle to 20%
    1. your prescaler is not set to 1:16 as said in the calc. Now, it's set to 1:4. Have a look in datasheet section 8.0 register 8-1 T2CON. you'll discover you need to use T2CON=%00000110

    2. duty=100 set a duty cycle of 16%... still as per the calc. 20% Duty=125

    Code:
    SerIn SI,T9600,,duty
    i think it's invalid.

    you should try
    Code:
    SerIn SI,T9600,#duty
    In Microcode Studio serial communicator, you have access to the settings. Right to 'send' button there's a little arrow.. click on it, go to line terminator, then check 'No terminator'
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  14. #14
    bennamanna's Avatar
    bennamanna Guest


    Did you find this post helpful? Yes | No

    Smile

    Gday,

    I changed the items you found to be in correct. It still will not output what I send via RS232. It comes up with other numbers. I will repost the code I have ended up with below.

    INCLUDE "modedefs.bas" ' Include serial modes
    SI VAR PORTB.1 ' Serial Input pin
    B0 VAR BYTE
    Define OSC 10

    Define LCD_DREG PORTA ' RA0..3
    Define LCD_DBIT 0
    Define LCD_RSREG PORTA ' RA6
    Define LCD_RSBIT 6
    Define LCD_EREG PORTA ' RA4
    Define LCD_EBIT 4
    Define LCD_BITS 4
    TRISA = 0
    TRISB = 0
    CMCON = 7

    Pause 1000 ' Wait for LCD to startup

    duty VAR word ' Duty cycle value (CCPR3L:CCP3CON<5:4>)

    TRISB.3 = 0 ' Set PORTB.5 (CCP3) to output
    CCP1CON = %00001100 ' Set CCP3 to PWM
    T2CON = %00000110 ' Turn on Timer2, Prescale=6

    PR2 = 155 ' Set PR2 to get 1KHz out
    duty = 125 ' Set duty cycle to 20%

    loop:
    SerIn SI,T9600,,# duty

    if duty > 625 then
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut "Duty to great" ' Display line 1
    goto loop
    endif

    CCP1CON.4 = duty.0 ' Store duty to registers as
    CCP1CON.5 = duty.1 ' a 10-bit word
    CCPR1L = duty >> 2

    'duty = duty + 5 ' Increase duty cycle
    LCDOut $FE,1 ' Clear LCD screen
    LCDOut # duty ' Display line 1

    GoTo loop ' Do it forever



    Any other ideas?

    Thanks,

    Ben

  15. #15
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Try this one. I don't use LCD but echo the results to the PC.
    Code:
    @     __CONFIG  _HS_OSC & _MCLRE_ON  &  _LVP_OFF & _WDT_OFF & _PWRTE_ON  & _BODEN_ON  
    DEFINE OSC 10
    
    CMCON = 7
    PORTA = 0
    PORTB = 0
    TRISA = 0
    TRISB = %00000010
    
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_SPBRG 64  ' 9600 Baud @ 0.16%
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    
    Duty    VAR WORD      ' Duty cycle value (CCPR1L:CCP1CON<5:4>)
    
    CCP1CON = %00001100   ' PWM mode
    T2CON = %00000110     ' Turn on Timer2, Prescale=1:16
    
    PR2 = 155             ' Set PR2 to get 1KHz out
    duty = 125            ' Set duty cycle to 20%
    GOSUB ChangeDuty
    
    Loop:
        HSerIn [DEC Duty]
        IF Duty > 625 THEN
           HSEROUT ["Duty too high... MAX = 625",13,10]
           ELSE
               GOSUB ChangeDuty
               HSEROUT ["Duty=",DEC Duty,13,10]
           ENDIF
        GOTO Loop
        
    ChangeDuty:
        CCP1CON.4 = Duty.0 ' Store duty to registers as
        CCP1CON.5 = Duty.1 ' a 10-bit word
        CCPR1L = Duty >> 2
        RETURN
    and read the FAQ about the fuse config... i think it's your main problem.

    So far, it's working here.
    Last edited by mister_e; - 13th November 2006 at 05:27.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Changing bits in a byte for multiple output
    By tazntex in forum Serial
    Replies: 3
    Last Post: - 11th August 2008, 19:10
  2. What's the voltage on output pin when it's HIGH?
    By TonyA in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 23rd April 2008, 15:06
  3. make a low voltage output from a PIC pin
    By emptyset in forum General
    Replies: 1
    Last Post: - 8th February 2008, 19:20
  4. Serious Serial Situation Setbacks...
    By Dansdog in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 7th February 2007, 03:46
  5. Help with final project
    By OvERKiLL in forum General
    Replies: 4
    Last Post: - 15th December 2006, 20:35

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