USB issue - 18F4550


Closed Thread
Results 1 to 15 of 15
  1. #1
    Join Date
    Oct 2009
    Posts
    583

    Default USB issue - 18F4550

    Hi Guys,

    need some advice as I'm going crazy trying to figure out what I've screwed up in the code I'm using.

    A good friend of mine wrote a very basic project to control some aquarium lights. His code basically uses four CASE statements per channel to set the on time for channel 1 & 2, the ramp up time for each channel, the duration both channels are on, and the fade down duration. So for example channel one could come on at 10:00, channel two on at 10:15, both then fade up to full brightness by 11:00, channel one then begin to fade down at 20:00, turning off at 21:00, with channel two fading between 20:30 and 22:00 for example. That part works fine.

    To make life easy my friend wrote a small windows application so that the on / off, fade durations etc could all be set by sliders and then the values squirted to the chip, which was originally an 18f2550. As I need more pins as I am developing his project further (with his permission) I've opted for an 18F4550. I was originally using a 20Mhz Xtal and with the following settings

    Code:
    ASM  ; 18F2550/4550, 20mhz crystal
       __CONFIG    _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
       __CONFIG    _CONFIG1H, _FOSC_HSPLL_HS_1H
       __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
       __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
       __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
       __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ENDASM
    DEFINE OSC 48
    CLEAR
    The PC picks up the connection and the USB device was reported as being installed successfully. His application loads, and automatically reads the values from the PICs eprom settings and moves the sliders and displays the numbers as per the default values that are entered. However, if the sliders are changed and the "update" button is pressed the new values are not written back to the chip.

    The code uses DT_HID260 which I'm guessing is something written by Darrel.

    Code:
    '****************************************************************
    'Setup Interrupts
    '****************************************************************
    INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"
    ASM
    INT_LIST  macro    ; IntSource,          Label,  Type, ResetFlag?
            INT_Handler   USB_Handler
            INT_Handler     TMR1_INT,  _MyTimer,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    endasm
    T1CON = %10000001                               ; free-running, 1:1 prescaler
    @   INT_ENABLE   TMR1_INT                       ; enable Timer1 interrupts
    
    '****************************************************************
    'Setup USB
    '****************************************************************
    INCLUDE "DT_HID260.pbp"
    
    DEFINE USB_VENDORID    6017
    DEFINE USB_PRODUCTID   1969
    DEFINE USB_VERSION     1
    DEFINE USB_VENDORNAME  "CSL Designs"
    DEFINE USB_PRODUCTNAME "Aqua-LED"
    DEFINE USB_SERIAL      "001"
    DEFINE USB_INSIZE      64   ;  IN report is PIC to PC (8,16,32,64)
    DEFINE USB_OUTSIZE     64   ; OUT report is PC to PIC
    DEFINE USB_POLLIN      10   ; Polling times in mS, MIN=1 MAX=10
    DEFINE USB_POLLOUT     10
    
    '****************************************************************
    The actual bit that gets called to do the USB comms is

    Code:
    SendUSB:
            for i = 0 to USBBufferCount - 1
                read i,USBTXBuffer[i]    'Read the eeprom data and store in the outward bound buffer
            next i
    SendData:
            USBOut 1, USBTXBuffer, USBBufferCount , SendDATA  ' if bus available, transmit data
            return
    
    GetUSB:
            USBin 1, USBRXBuffer, USBBufferCount, Timeout  ' if bus available, receive data
            if Firstsend = 0 then
                for i = 0 to USBBufferCount - 1
                    write i,USBRXBuffer[i]    'Write the eeprom data received from the PC
                next i
            gosub Read_eeprom                 'Read eeprom data into the variables
            else
                Firstsend = 0
            endif
    Timeout:
            return       
            
    ' If USB plugged display USB on the display
    USB_Plugged:
        if plugged = 0 then
        lcdout $FE,$91,"   "
        else
        lcdout $FE,$91,"USB"
        endif
        return
    I've tried removing the timeout option and substituting it for the getUSB so it loops and that didin't work, I've also tried using a 4Mhz resonator with the same fuse settings as the 2550 chip and that still fails to update

    Code:
     ASM
    __CONFIG    _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L  
                            ;              ;                      ; USB clock source comes from the 96 MHz PLL divided by 2
                            ;              ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
                            ; No prescale (4 MHz oscillator input drives PLL directly)
    
                                                                 
    __CONFIG    _CONFIG1H, _FOSC_XTPLL_XT_1H  & _IESO_OFF_1H 
                            ;                  ;               ; Oscillator Switchover mode disabled
                            ;                  ; Fail-Safe Clock Monitor disabled
                            ; XT oscillator, PLL enabled, XT used by USB
                            
    __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L  & _BORV_2_2L  & _VREGEN_ON_2L   
    __CONFIG    _CONFIG2H, _WDT_OFF_2H 
    __CONFIG    _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H 
    __CONFIG    _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L 
    endasm
    DEFINE OSC 48
    clear
    I've also checked the settings for PORT.C to make sure it's not all set to output - still no joy.

    I would welcome suggestions on things to try, or point me to where the problem may be.... My friend thinks it must be a timing issue, which when I was running with a 20 Mhz and a divide/5 prescaler I might of agreed (however I would of thought that if this was the case then windows would of reported a device not recognised error), but then even using the 4Mhz resonator (which doesn't seem to make the code run any slower, so I would be happy with that for the performance) still didn't work.

    Thanks in advance...

    Malcolm

  2. #2
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Edit. I noticed this in the code
    Code:
    if RX_READY = 1 and plugged = 1 then gosub GetUSB
    So using the LCD to debug I've found RX_READY is 0 when the cable is connected and the application on the PC running - Looking at the DT_HID260 code, this variable is set within that code --- DT help !!!

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Hi Malcolm,

    I'm affraid there's not enough code posted to be able to find your problem.
    I think what you've posted is the part you've gone over a hundred times and couldn't see anything wrong. So maybe there's nothing wrong there.
    It's likely the problem is somewhere else.

    The RX_READY bit is simply copied from the Hardware USB status register on every USB interrupt.
    If it never goes high, then either nothing is being sent from the PC, or the data has been collected already before you displayed RX_READY on the LCD.
    I would suggest enabling the USB Status LED's so you can see what's happening in real time.

    Code:
    ; --- Each USB LED is optional, comment them if not used ----
    DEFINE USB_LEDPOLARITY 1       ; LED ON State [0 or 1]  (default = 1)
    DEFINE USB_PLUGGEDLED  PORTB,0 ; LED indicates if USB is connected
    DEFINE USB_TXLED       PORTC,2 ;  "      "     data being sent to PC
    DEFINE USB_RXLED       PORTC,1 ;  "      "     data being received from PC
    DT

  4. #4
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Hi Darrel,

    Here's the full code, which I hope might help. I have tried a USB scanner and got the attached results.. which mean nothing to me, other than it throws up some errors when the PC software was launched.

    Code:
    @ errorlevel -205
    
    '****************************************************************
    ' Config settings
    '****************************************************************
    
    asm
    
    ; 18F2550/4550, 20mhz crystal
       __CONFIG    _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
       __CONFIG    _CONFIG1H, _FOSC_HSPLL_HS_1H
       __CONFIG    _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _VREGEN_ON_2L
       __CONFIG    _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H
       __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
       __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
    ENDASM
    DEFINE OSC 48
    CLEAR
    
    
    '****************************************************************
    
    ADCON0 = 0          'Set ADCON0
    ADCON1 = %00001111  'Set D i/o
    CMCON = 7           'Disable Comparators
    CCP1CON = %00001100 'set pwm  white  - pin12
    CCP2CON = %00001100 'set pwm  blue   - pin12
    TRISA  = %00000000  'set PORTA as all output
    TRISB  = %00000011  'set PORTB as all output
    TRISC  = %01011000  'set PORTC as all output apart from port 6 used for backlight button
    PR2 = 249                      
    'T2CON = %00000100   ' Start Timer2, Prescaller 1:1
    '****************************************************************
    
    DEFINE LCD_DREG PORTB       ' Setup the ports for the LCD (as not set to the default layout as set in PBP)
    DEFINE LCD_DBIT 0           ' Set starting Data bit (0 or 4) if 4-bit bus
    DEFINE LCD_RSREG PORTB      ' Set LCD Register Select port
    DEFINE LCD_RSBIT 4          ' Set LCD Register Select bit
    DEFINE LCD_EREG PORTB       ' Set LCD Enable port
    DEFINE LCD_EBIT 5           ' Set LCD Enable bit
    DEFINE LCD_BITS 4           ' Set LCD bus size (4 or 8 bits)
    DEFINE LCD_LINES 4          ' Set number of lines on LCD
    DEFINE LCD_COMMANDUS 2000   ' Set command delay time in us
    DEFINE LCD_DATAUS 50        ' Set data delay time in us
    '****************************************************************
    LCD_BACKLIGHT   var PORTB.7     'Set port b .7 for LCD backlight (High = on)
    PBUTTON         var PORTC.6     'set PORTC.6 for the button for the lcd
    SDA_Pin         var PORTB.0     'RTC SDA Data pin
    SCL_Pin         var PORTB.1     'RTC SCL clock pin
    
    CounterA var byte	               ' General purpose Variable
    CounterB var byte	               ' General purpose Variable
    option            var byte 
    H_butt   VAR PORTE.2
    M_butt   VAR PORTE.0
    S_butt   VAR PORTE.1
    
    '****************************************************************
    i               var word        'Misc counter
    iv              var word
    LCD_Mode        var word        'LCD light mode
    LCD_Timer       var word        'Timer for how long the LCD is on for.
    LCD_Time        var word        'Counter for the timer
    LCD_Tmr         var word
    
    '****************************************************************
    ' Temp probes
    Temperature var word[4]
    
    Temperature1    var temperature[0]
    Temperature2    var Temperature[1]
    Temperature3    var Temperature[2]
    Temperature4    var Temperature[3]
    
    '****************************************************************
    ' RTC Variables
    
    
    'RTC_Msecs       var byte
    RTC_Secs        var byte
    RTC_Mins        var byte
    RTC_Hours       var byte
    RTC_Day         var byte
    RTC_WDay        var byte
    RTC_Month       var byte
    RTC_Year        var byte
    RTC_Ctrl        var byte
    dummy           var byte
    RTclock         var byte[8]
    Tick_Tmr        var byte
    
    SetupPreset:
    	RTC_Secs=$00		             ' Seconds preset to 00
    	RTC_Mins=$59		             ' Minutes preset 
    	RTC_Hours=$09		             ' Hours preset 
    	RTC_WDay=$01		             ' Weekday preset to 01
    	RTC_Day=$12		                 ' Day preset 12
    	RTC_Month=$06	                 ' Months preset to June
    	RTC_Year=$02		             ' Year preset to 2002
    	RTC_Ctrl=$10
    
    '****************************************************************
    ' LED variables
    ' Whites:
    W_Min           var word    'Min Light value
    W_Max           var word    'Max Light value
    W_Fade_In       var word    'Fade in duration
    W_Fade_Out      var word    'Fade out duration
    W_On_Time_H     var word    'What time to turn the lights on
    W_On_Time_M     var word    'What time to turn the lights on
    W_Off_Time_H    var word    'Time to turn lights off
    W_Off_Time_M    var word    'Time to turn lights off
    
    ' Blues:
    B_Min           var word    'Min Light value
    B_Max           var word    'Max Light value
    B_Fade_In       var word    'Fade in duration
    B_Fade_Out      var word    'Fade out duration
    B_On_Time_H     var word    'What time to turn the lights on
    B_On_Time_M     var word    'What time to turn the lights on
    B_Off_Time_H    var word    'Time to turn lights off
    B_Off_Time_M    var word    'Time to turn lights off
    
    'Running fade variables
    B_FadeIn_Time   var word    'LIVE fade delay time seconds
    B_FadeOut_Time  var word
    W_FadeIn_Time   var word
    W_FadeOut_Time  var word
    B_Cnt           var word    'Seconds counter for the timing of adjusting the PWM
    W_Cnt           var word
    B_Tick          var word
    W_Tick          var word
    
    'PWM Variables where the current output values are stored
    W_PWM           var word    'Whites
    B_PWM           var word    'Royal Blues
    
    '****************************************************************
    Blue_Day_Cycle      var word    'Store for which part of the day cycle we are in
    White_Day_Cycle     var word
    
    ' Constants for the current running mode cycle for the lights
    DAWN    con     0
    DAY     con     1
    DUSK    con     2
    NIGHT   con     3
    
    '****************************************************************
    'Expendable variables used for misc calculations etc
    Vb_1            var word
    Vb_2            Var word
    Vb_3            var word
    Vb_4            var word
    
    '****************************************************************
    USBBufferCount  Var Byte
    
    Firstsend       var byte        ' When first connected the pc auto sends data, but we want to READ first otherwise
                                    ' the eeprom gets overwritten with zeros as the pc sends a packet we DONT want.                           
    '****************************************************************
    ' Set default data in internal EEPROM
    
        data @0
        data    10      'Whites ON Time HOURS 
        data    00       'Whites ON Time MINS  
        data    10      'Whites OFF Time HOURS
        data    10       'Whites OFF Time MINS
        data    0       'Whites Fade IN duration HOURS
        data    5      'Whites Fade IN duration MINS
        data    0       'Whites Fade OUT duration HOURS
        data    3       'Whites Fade OUT duration MINS
        data    0       'Whites MIN Intensity %
        data    100      'Whites MAX Intensity %
    
        data    10      'Blues ON Time HOURS
        data    0       'Blues ON Time MINS
        data    10      'Blues OFF Time HOURS
        data    10       'Blues OFF Time MINS
        data    0       'Blues Fade IN duration HOURS
        data    5       'Blues Fade IN duration MINS
        data    0       'Blues Fade OUT duration HOURS
        data    5       'Blues Fade OUT duration MINS
        data    0       'Blues MIN Intensity %
        data    100      'Blues MAX Intensity %
        
        Data @150,74,97,110,70,101,98,77,97,114,65,112,114
    		' Jan Feb Mar Apr
    	Data 77,97,121,74,117,110,74,117,108,65,117,103
    		' May Jun Jul Aug
    	Data 83,101,112,79,99,116,78,111,118,68,101,99
    		' Sep Oct Nov Dec
    	Data 84,117,101,87,101,100,84,104,117,70,114,105
    		' Tue Wed Thu Fri
    	Data 83,97,116,83,117,110,77,111,110
    		' Sat Sun Mon
        
    '****************************************************************
    'Setup Interrupts
    '****************************************************************
    INCLUDE "DT_INTS-18.bas"     ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"
    ASM
    INT_LIST  macro    ; IntSource,          Label,  Type, ResetFlag?
            INT_Handler   USB_Handler
            INT_Handler     TMR1_INT,  _MyTimer,   PBP,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    endasm
    T1CON = %10000001                               ; free-running, 1:1 prescaler
    @   INT_ENABLE   TMR1_INT                       ; enable Timer1 interrupts
    
    '****************************************************************
    'Setup USB
    '****************************************************************
    INCLUDE "DT_HID260.pbp"
    
    DEFINE USB_VENDORID    6017
    DEFINE USB_PRODUCTID   1969
    DEFINE USB_VERSION     1
    DEFINE USB_VENDORNAME  "CSL Designs"
    DEFINE USB_PRODUCTNAME "Aqua-LED"
    DEFINE USB_SERIAL      "001"
    DEFINE USB_INSIZE      64   ;  IN report is PIC to PC (8,16,32,64)
    DEFINE USB_OUTSIZE     64   ; OUT report is PC to PIC
    DEFINE USB_POLLIN      10   ; Polling times in mS, MIN=1 MAX=10
    DEFINE USB_POLLOUT     10
    
    '****************************************************************
    ' Start the program
    '****************************************************************
    code_start:
       ' i2cwrite SDA_Pin,scl_pin,$D0,$00,[$00,$00,$00,$59,$19,$24,$08,$00]
        I2Cwrite SDA_pin,SCL_pin,$D0,$00,[RTC_Secs,RTC_Mins,RTC_Hours,RTC_WDay,RTC_Day,RTC_Month,RTC_Year,RTC_Ctrl]
        Blue_Day_Cycle = DAWN
        White_Day_Cycle = DAWN
        b_cnt = 0
        w_cnt = 0
        
        gosub   read_eeprom     'Read in the data needed for the lighting periods    
         
        Firstsend = 1
        USBBufferCount = 64     'Size of the USB buffer we use
    
        LCD_Mode = 3            'LCD Backlight always ON
        LCD_Time = 0            'Both these are used for the duration the backlight                            
        LCD_Tmr = 0             'is on when not in mode 3.
    
        gosub Calc_Fade
    
        high LCD_BACKLIGHT
    
        LCDOUT  $FE,1
    ' Display splash screen
    
        lcdout  $FE,$C0,"    AquaLED V1.0    "
        lcdout  $FE,$94,"  (C)2010 M.Jervis  "
        pause   1000   'wait a seconds so they can see it
        lcdout  $FE,1   'Clear the screen
    
    
    
    '****************************************************************
    'Main program loop
    '****************************************************************
    main:
        'Main body of program where we determine which time of day we are in
    
    
    
    '*** Do BLUE daily cycle
        select case Blue_Day_Cycle
        case DAWN
        lcdout $FE,$94,"BL: DAWN "
            if b_cnt = B_Fadein_time and B_PWM < B_Max then
                B_PWM = B_PWM + 1
                b_cnt = 0
            endif
            if B_PWM = b_max then
                Blue_Day_Cycle = DAY
            endif
        case DAY
        lcdout $FE,$94,"BL: DAY  "
            if RTC_Hours = B_Off_Time_H and RTC_Mins = B_Off_Time_M then
                Blue_Day_Cycle = DUSK
                b_cnt = 0
            endif 
        CASE DUSK
        lcdout $FE,$94,"BL: DUSK "
            if b_cnt >= B_Fadeout_time and B_PWM > B_Min then
                B_PWM = B_PWM - 1
                b_cnt = 0
            endif
            if B_PWM = b_min then 
                Blue_Day_Cycle = NIGHT
            endif
        case NIGHT
        lcdout $FE,$94,"BL: NIGHT"
            if RTC_Hours = B_On_Time_H and RTC_Mins = B_On_Time_M then
                Blue_Day_Cycle = DAWN
                b_cnt = 0
            endif 
        end select
    
    '*** Do WHITE daily cycle
        select case White_Day_Cycle
        case DAWN
        lcdout $FE,$94+11,"WT: DAWN "
            if w_cnt = w_Fadein_time and W_PWM < w_max then
                W_PWM = W_PWM + 1
                w_cnt = 0
            endif
            if W_PWM = W_max then White_Day_Cycle = DAY
        case DAY
        lcdout $FE,$94+11,"WT: DAY  "
            if RTC_Hours = W_Off_Time_H and RTC_Mins = W_Off_Time_M then
                White_Day_Cycle = DUSK
                w_cnt = 0
            endif 
        CASE DUSK
        lcdout $FE,$94+11,"WT: DUSK "
            if w_cnt >= w_Fadeout_time and W_PWM > w_min then
                W_PWM = W_PWM - 1
                w_cnt = 0
            endif
            if W_PWM = W_min then White_Day_Cycle = NIGHT
        case NIGHT
        lcdout $FE,$94+11,"WT: NIGHT"
            if RTC_Hours = W_On_Time_H and RTC_Mins = W_On_Time_M then
                White_Day_Cycle = DAWN
                w_cnt = 0
            endif 
        end select
    
        hpwm 1,W_PWM,1500        
        hpwm 2,B_PWM,1500
    
    
        gosub Read_Clock
            
    
        i = (((RTC_Secs>>4)&$0F)*10)+(RTC_Secs&$0F)
        lcdout $FE,$80,"BLUES  ",dec3 (B_PWM *100)/255,"%"
        lcdout $FE,$C0,"WHITES ",dec3 (W_PWM *100)/255,"%"
    
        gosub   USB_Plugged
       
        if TX_READY = 1 and plugged = 1 then gosub SendUSB
        if RX_READY = 1 and plugged = 1 then gosub GetUSB 
        if plugged = 0 then FirstSend = 1   'If we unplug then reset the first read packet as dont want it!
        lcdout $FE,$D4+6," ",dec RX_READY
    '**** FINSISH BUTTON CODE ****
        if PBUTTON = 1 then
            LCDOUT $FE,1
            goto mainmenu
        endif
        goto main  
    
    
    '****************************************************************
    ' LCD Backlight time
    ' Keeps the LCD backlight on until time is met unless its set to
    ' always on.
    '****************************************************************
    LCD_Blight:
        if LCD_Mode = 0 then        '10 seconds
            LCD_Timer = 10
        elseif LCD_Mode = 1 then    '30 seconds
            LCD_Timer = 30
        else
            LCD_Timer = 60          '1 minute
        endif
        LCD_Time = LCD_Time + 1
        if LCD_Time = 100 then
            LCD_Tmr = LCD_Tmr + 1
            LCD_Time = 0
        endif
        if LCD_Tmr >= LCD_Timer then
            low LCD_BACKLIGHT
            LCD_Tmr = 0
            LCD_Time = 0
        endif
        return
    
    '****************************************************************
    ' USB Services.
    ' Send and recieve data packets
    '
    ' Packet sizes are 64 bytes which should cover the amount of
    ' data we need for now.
    '****************************************************************
    SendUSB:
            for i = 0 to USBBufferCount - 1
                read i,USBTXBuffer[i]    'Read the eeprom data and store in the outward bound buffer
            next i
    SendData:
            USBOut 1, USBTXBuffer, USBBufferCount , SendDATA  ' if bus available, transmit data
            return
    
    GetUSB:
            USBin 1, USBRXBuffer, USBBufferCount, Timeout  ' if bus available, receive data
            if Firstsend = 0 then
                for i = 0 to USBBufferCount - 1
                    write i,USBRXBuffer[i]    'Write the eeprom data received from the PC
                next i
            gosub Read_eeprom                 'Read eeprom data into the variables
            else
                Firstsend = 0
            endif
    Timeout:
            return       
            
    ' If USB plugged display USB on the display
    USB_Plugged:
        if plugged = 0 then
        lcdout $FE,$91,"   "
        else
        lcdout $FE,$91,"USB"
        endif
        return
     
    '******************************************************************
    ' LED Fade calculations
    ' This routine takes the fade in/out durations and also the min/max
    ' LED power values and calculates what the duration is between
    ' changing the PWM value to give us a smooth fade from min to max
    Calc_Fade:
        vb_1 = ((b_fade_in.highbyte * 60) + b_fade_in.lowbyte) *60  'Get total duration time in seconds
        vb_2 = b_max - b_min                                        'Work out the 'distance' the lights go from min to max
        b_fadein_time = vb_1 / vb_2                                 'Get number of seconds between each PWM change    
        vb_4 = vb_1 // vb_2                                         'Get fractions of a second
        if vb_4 >=5 then b_fadein_time = b_fadein_time + 1          'If its over half a second then round up
    
        vb_1 = ((b_fade_out.highbyte * 60) + b_fade_out.lowbyte) *60
        b_fadeout_time = vb_1 / vb_2    
        vb_4 = vb_1 // vb_2                                         'Get fractions of a second
        if vb_4 >=5 then b_fadeout_time = b_fadeout_time + 1        'If its over half a second then round up
    
        vb_1 = ((w_fade_in.highbyte * 60) + w_fade_in.lowbyte) *60   
        vb_2 = w_max - w_min                            
        w_fadein_time = vb_1 / vb_2                         
        vb_4 = vb_1 // vb_2                                         'Get fractions of a second
        if vb_4 >=5 then w_fadein_time = w_fadein_time + 1          'If its over half a second then round up
    
        vb_1 = ((w_fade_out.highbyte * 60) + w_fade_out.lowbyte) *60 
        w_fadeout_time = vb_1 / vb_2                         
        vb_4 = vb_1 // vb_2                                         'Get fractions of a second
        if vb_4 >=5 then w_fadeout_time = w_fadeout_time + 1        'If its over half a second then round up
        return
        
        'Lets say 2 hours (120 mins) & 191 for the fade amount (ie 0 to 255 or 0% to 100% intensity)
        'So we need to do:
        ' convert hours into minutes, then add minutes and then multiply by 60 to convert to seconds
        ' so: 2 hours = 120 mins + 0 mins * 60 to get 7200 seconds
        ' The distance is now based on the converted % into the PWM range of 0-255
        ' calculate the 'distance' the light goes from min to max (0 to 255 in this eg: 75% = 191 so: 191- 0 = 191)
        ' now divide total seconds by 'distance' ie: 7200 / 191 = 37.69 seconds between each PWM change
        ' Now we test the milliseconds and if above .5 we round up to the next second
    
        
    '******************************************************************
    ' Check current time and adjust the position in the cycle to
    ' make sure that its where it should be in case of a power failure
    ' or if the settings are changed via the PC
    Check_Lighting:
        if rtc_hours < b_on_time_h then                 'Are we earlier than the fade in time?
            blue_day_cycle = NIGHT                      'Yes so set the current mode to night
            white_day_cycle = NIGHT
        elseif rtc_hours > b_off_time_h then            'Are we later than time off?
            vb_1 = b_off_time_h + b_fade_out.highbyte   'need to find out if were actually past the end of the fade out time
            vb_2 = b_off_time_m + b_fade_out.lowbyte    
            if vb_2 > 59 then                           'if the minutes are more than 59 
                vb_1 = vb_1 + 1                         'then add 1 to the hour
                vb_2 = vb_2 - 60                        'Adjust the minutes back to between 0-59
            endif
            if rtc_hours > vb_1 and rtc_mins > vb_2 then
                blue_day_cycle = NIGHT                  'Yes so set the current mode to NIGHT
                white_day_cycle = NIGHT
            else
                blue_day_cycle = DUSK                   'No, were inbetween so set to DUSK
                white_day_cycle = DUSK
    
                vb_1 = rtc_hours - b_off_time_h          'Calculate the time difference between on time and current time
                vb_2 = rtc_mins - b_off_time_m
                vb_3 = (vb_1 * 3600) + (vb_2 * 60)      'Convert all to seconds
                B_PWM = B_max - (vb_3 / b_fadeout_time)   'Divide by the seconds count between each PWM to get how far we are in
    
                vb_1 = rtc_hours - w_off_time_h          'Calculate the time difference between on time and current time
                vb_2 = rtc_mins - w_off_time_m
                vb_3 = (vb_1 * 3600) + (vb_2 * 60)      'Convert all to seconds            
                W_PWM = w_max - (vb_3 / w_fadeout_time)   'Divide by the seconds count between each PWM to get how far we are in                      
            endif
        else
            vb_1 = w_on_time_h + w_fade_in.highbyte     'need to find out if were actually past the end of the fade out time
            vb_2 = w_on_time_m + w_fade_in.lowbyte    
            if vb_2 > 59 then                           'if the minutes are more than 59 
                vb_1 = vb_1 + 1                         'then add 1 to the hour
                vb_2 = vb_2 - 60                        'Adjust the minutes back to between 0-59
            endif
            if rtc_hours > vb_1 and rtc_mins > vb_2 then
                blue_day_cycle = DAY                    'Yes so set the current mode to DAY
                white_day_cycle = DAY
                B_PWM = B_MAX
                W_PWM = w_max
            else
                blue_day_cycle = DAWN                   'No, were inbetween so set to DAWN
                white_day_cycle = DAWN
    
                vb_1 = rtc_hours - b_on_time_h          'Calculate the time difference between on time and current time
                vb_2 = rtc_mins - b_on_time_m
                vb_3 = (vb_1 * 3600) + (vb_2 * 60)      'Convert all to seconds
                B_PWM = b_min + (vb_3 / b_fadein_time)  'Divide by the seconds count between each PWM to get how far we are in
    
                vb_1 = rtc_hours - w_on_time_h          'Calculate the time difference between on time and current time
                vb_2 = rtc_mins - w_on_time_m
                vb_3 = (vb_1 * 3600) + (vb_2 * 60)      'Convert all to seconds
                W_PWM = w_min + (vb_3 / w_fadein_time)  'Divide by the seconds count between each PWM to get how far we are in
            endif        
        endif
        return    
    '******************************************************************
    ' Read Eeprom data into variables
    Read_eeprom:
        read 0,w_on_time_h              'Whites ON time hours
        read 1,w_on_time_m              'Whites ON time minutes
        read 2,w_off_time_h             'Whites OFF time hours
        read 3,w_off_time_m             'Whites OFF time minutes
        read 4,w_fade_in.highbyte       'Whites fade IN duration hours
        read 5,w_fade_in.lowbyte        'Whites fade IN duration minutes
        read 6,w_fade_out.highbyte      'Whites fade IN duration hours
        read 7,w_fade_out.lowbyte       'Whites fade IN duration minutes
        read 8,w_min                    'Whites MIN intensity
        read 9,w_max                    'Whites MAX intensity             
        read 10,b_on_time_h             'Whites ON time hours
        read 11,b_on_time_m             'Whites ON time minutes
        read 12,b_off_time_h            'Whites OFF time hours
        read 13,b_off_time_m            'Whites OFF time minutes
        read 14,b_fade_in.highbyte      'Whites fade IN duration hours
        read 15,b_fade_in.lowbyte       'Whites fade IN duration minutes
        read 16,b_fade_out.highbyte     'Whites fade IN duration hours
        read 17,b_fade_out.lowbyte      'Whites fade IN duration minutes
        read 18,b_min                   'Whites MIN intensity
        read 19,b_max                   'Whites MAX intensity             
        
        W_Min = (W_Min *255)/100        'Convert intensity % to real PWM value (from 0-100% to 0-255)
        W_Max = (W_Max *255)/100
        B_Min = (B_Min *255)/100
        B_Max = (B_Max *255)/100
        gosub Read_Clock
        gosub Check_Lighting
        return
    
    
    '******************************************************************
    Read_Clock:
    
    I2CRead SDA_pin,SCL_pin,$D0,$00,[RTC_Secs,RTC_Mins,RTC_Hours,RTC_WDay,RTC_Day,RTC_Month,RTC_Year,RTC_Ctrl]
    If RTC_Hours.6=1 then			
    CounterA=(RTC_Hours>>4)&$01                           ' Work-Out 12 or 24 hour Display for Hours
    else
    CounterA=(RTC_Hours>>4)&$03
    endif
    CounterA=CounterA*10+(RTC_Hours&$0F)                  ' Display Hours appropriately for 12 or 24 hour Mode 
    If RTC_Hours.6=1 then
    			
    LCDOut $FE,$D4,#CounterA
    else
    LCDOut $FE,$D4,#CounterA Dig 1,#CounterA Dig 0
    endif
    
    LCDOut ":",#(RTC_Mins>>4)&$0F,#RTC_Mins&$0F
    
     i = (((RTC_Hours>>4)&$0F)*10)+(RTC_Hours&$0F)
        rtc_hours = i
        i = (((RTC_Mins>>4)&$0F)*10)+(RTC_Mins&$0F)
        rtc_mins = i
        
    
    Return  
    
    
    '************************************
    
    
    MyTimer:
        Tick_Tmr = Tick_Tmr + 1
        if Tick_Tmr >107 then    
            Tick_Tmr = 0
            b_cnt = b_cnt + 1
            W_cnt = W_cnt + 1
        endif  
    @  INT_RETURN
      
    mainmenu:
    
    LCDOUT $FE,$80,"Setup Menu"
    lcdout $FE, $C0, "Select Option"
    
    IF Option = 1 THEN lcdout $FE, $D4, "Set Time and Date  "
    if option = 2 then lcdout $FE, $D4, "op2 "
    if option = 3 then lcdout $FE, $D4, "op3 "
    if option = 4 then lcdout $FE, $D4, "opt4"
    if option = 5 then lcdout $FE, $D4, "Run                "
    IF PBUTTON THEN Option = option + 1
    
    if option >5 then option = 1
    Pause 250   
    If option = 1 Then
    If S_butt = 0 Then
    LCDOUT $FE,1 
    'Gosub SetButtonRelease
    'goto  setup
    endif
    endif
    
    
    If option = 2 Then
    If S_butt = 0 Then 
    LCDOUT $FE,1
    'Gosub SetButtonRelease
    'goto opt2
    endif
    endif
    
    
    If option = 3 Then
    If S_butt = 0 Then 
    LCDOUT $FE,1
    'Gosub SetButtonRelease
    'goto opt3
    endif
    endif
    
    If option = 4 Then
    If S_butt = 0 Then
    LCDOUT $FE,1 
    'Gosub SetButtonRelease
    'goto opt4
    endif
    endif
    
    If option = 5 Then
    If S_butt = 0 Then
    LCDOUT $FE,1 
    'Gosub SetButtonRelease
    goto main
    endif
    endif
    
    
    Goto mainmenu
    Attached Images Attached Images  

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Malcolm,

    I'm running your program here on a LAB-XUSB.
    I had to change some things to make it run on it. And I made a program for the PC to just send/receive some data over USB.

    Your program is sending out 127 reports per second when the USB is plugged in.
    I'm not sure if your friends PC app can handle that many reports while updating GUI sliders etc..
    It also fills up the USB buffer before the PC app connects, so when it does connect, it gets hit hard with a whole bunch of reports.

    When I send data to it via USB, it saves the data to EEPROM and continues sending the new data at 127 reports per second.

    So the USB portion is working properly.
    You just need to limit the data going out.
    It should really only send the data by request from the PC, instead of all the time.

    This was all quite evident after adding the USB status LED's from post #3.
    DT

  6. #6
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Darrel,

    thanks for taking the time out to test the code and report your findings.

    I assume that ideally the PC program should send a request to the PIC, which then responds and sends the report, rather than the PIC constantly sending out reports when connected ?

    I'll drop the guy a mail to see if he can come up with a revised application.

    Your contribution is very much appreciated

    Malcolm

  7. #7
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    A simple interim step might be sending only 1 report per second or even less. There'll be lots of work to get a query/response protocol going and a simple slow down might meet your needs for this one-off project, or at least let you work other areas of the code while you're waiting for PC side changes.

  8. #8
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Hi Charlie,

    Yes I have other parts of the code to develop, and whilst it would be a nice function to have, I can live without it if I must.

    To prove it wasn't a duff chip or hardware issue with the USB port on the EasyPic5 board I downloaded the USB Demo example (Mr E's) and stuck a 4mhz resonator in the board - it ran fine and I could toggle the LEDS on portB from the PC application. I then swapped the resonator for a 20 mhz xtal and set the fuses in the programmer accordingly and tested again - it ran sweetly. So the issue is with the code, and I have no reason to doubt DT's explanation.

    Thanks for the comments

    Malcolm

  9. #9
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    @Darrel,

    Hi, need some advice regarding the way the HID260 USB routine works.

    I commented out the send section in my main code thus:
    Code:
     ;   if TX_READY = 1 and plugged = 1 then gosub SendUSB
        if RX_READY = 1 and plugged = 1 then gosub GetUSB 
        if plugged = 0 then FirstSend = 1       'If we unplug then reset the first read packet as dont want it!
    So this way I can check the sending of data from the PC to PIC. As the software is written to read the EEPROM data from the PIC first, the application displayed garbage values in the sliders which was as expected. Opening up the port monitor I got one TX report for each time I clicked on the update button, and whilst I couldn't see what values I was sending to the PIC, the LCD appeared to respond and display the change of values.

    I removed the comment from that line and again the PIC was spewing report after report as you found. I therefore added the line

    Code:
    SendData:
        
            USBOut 1, USBTXBuffer, USBBufferCount , SendData  ' if bus available, transmit data
            plugged = 0
            return
    The theory being that once it's sent that first report the software would then behave as if the USB lead had been removed - there was no change when the USB port was monitored. So I tried the following

    Code:
            USBOut 1, USBTXBuffer, USBBufferCount , SendData  ' if bus available, transmit data
            TX_READY = 0
            return
    Again, my logic thinking that once the report had been sent and the TX_ready state set to "not ready" it would stop transmission - but again no change. It's as if something else is over-riding the values used, which originate in the included HID260 file. The code I'm using doesn't have any other calls or conditions connected with the USB, just those IF / THEN statements to check the status of ready and plugged, and then the send and receive routines. Can you advise where or why over-riding these variables have no effects.

    Cheers

    Malcolm

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    PLUGGED, RX_READY and TX_READY are status bits that DT_HID copies from the hardware USB registers on each USB interrupt.

    They allow your program to know the USB status.
    But they do not control anything.

    Why not just increment a variable, and only send data when it reaches 127.
    Then it should send it once a second.
    DT

  11. #11
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Thanks for the info,

    I've added a counter and condition as suggested and it does indeed now pole once a second, but I'm still getting the same issue, but this time it's easy to spot. I can move a slider, click update, but a second later it will revert back to it's default setting. Watching the port monitor, only RX reports are being shown. However if I comment out the part of the code which does the checks for TX ready and plugged, I can send updates from the PC, which is shown in the port monitor window. It's as if the RX part on the PIC side is being ignored

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    I'm guessing that you still haven't enabled the status LED's from post #3.
    Since you're using an EasyPIC board, you should have lots of LED's to use.
    It makes it a lot easier to see what's going on.

    The PIC program has no problem receiving data from my PC app.
    Can you post your friend's PC app?
    DT

  13. #13
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Hi Darrel,

    Sorry, no I've not had much chance of hooking up the LEDs to the USB activity... Looking at the manual for the EasyPIC5, setting the jumpers to route the D+ and D- etc from the socket to RC4 and RC5 results in these pins being disconnected from the rest of the board. I'll see if a breadboard approach might help.

    I've attached a zip file containing the PC software, hope that it helps
    Attached Files Attached Files

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    The Status LED's do not connect to the D+ or D- pins.
    You can use any pin besides those.

    And your problem is definately in the PC program you just posted.

    It does not update anything until it receives a report from the PIC.
    Even the clock in the bottom right corner only updates on each report from the PIC.

    If you make it so the PIC does not send anything, then the PC program will send updates.
    But as soon as the PIC sends something, the PC program will never send anything again.

    That program needs some serious work.
    Last edited by Darrel Taylor; - 20th February 2013 at 20:23.
    DT

  15. #15
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: USB issue - 18F4550 - DT_HID260

    Darrel,

    As stated, I didn't write the bulk of the code, as both it and the application was written by a friend, who said that back in 2006 it worked fine but on a different chip. I can confirm that he did indeed write the application to function in that way, ie the PIC sends data when it detects the USB connected and then sends updated data back once the update setting button is pressed. I agree a better approach would of been to have the application set the values and then simply update the PIC once the update button has been pressed. I could ask him if he still has the source code and if it can be modified to work that way.

    Thanks again for your input.

Similar Threads

  1. USB Electrical Layout?
    By wdmagic in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 11th March 2013, 12:04
  2. PIC USB in and USB Out
    By koossa in forum General
    Replies: 2
    Last Post: - 9th February 2013, 09:00
  3. 18F4550 issue
    By Christopher4187 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 4th February 2013, 06:27
  4. Wake from sleep with USB Interrupt
    By kduck63 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 13th January 2013, 00:59
  5. Bidirectional Excel Data via USB
    By jmstrat in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 2nd January 2013, 08:04

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