Page 30 of 41 FirstFirst ... 2026272829303132333440 ... LastLast
Results 291 to 300 of 405

Thread: The big TEC driver thread!

  1. #291
    Join Date
    Dec 2008
    Location
    Southport, UK
    Posts
    2,746

    Default

    Frank, you work for Terrex Demag!

    I don't suppose you can get your hands on the Terrex crane specifier software?

    To save time with long hand calculations I have created quite a complex Excel sheet. It calculates point loadings based on maximum imposed ground pressure, lift load, crane weight, lift radius, outrigger fulcrum, wind sail forces etc etc and flags warnings up, but I would really like to look at the official software if possible.

    Sorry for the the thread raid

    Following this thread with great interest and anticipation BTW.

    Ian
    http://img62.imageshack.us/img62/3985/laser.gif

    Doc's website

    The Health and Safety Act 1971

    Recklessly interfering with Darwin’s natural selection process, thereby extending the life cycle of dim-witted ignorami; thus perpetuating and magnifying the danger to us all, by enabling them to breed and walk amongst us, our children and loved ones.





  2. #292
    Join Date
    Jun 2010
    Location
    Zweibrücken, Germany
    Posts
    605

    Default

    Quote Originally Posted by Doc View Post
    Frank, you work for Terrex Demag!

    I don't suppose you can get your hands on the Terrex crane specifier software?

    To save time with long hand calculations I have created quite a complex Excel sheet. It calculates point loadings based on maximum imposed ground pressure, lift load, crane weight, lift radius, outrigger fulcrum, wind sail forces etc etc and flags warnings up, but I would really like to look at the official software if possible.

    Sorry for the the thread raid

    Following this thread with great interest and anticipation BTW.

    Ian
    Yeah Doc, I'm with Terex-demag for 15 years now in R&D and production control/Testing. I know the software you'r talking about but I don't know how it is distributed. I'll check into it. It's actually more of a costomer tool. I take it you know a little about cranes? I do software, electroncis and testing here for mainly mobile telescopic cranes from 40-1000t. Bringing the R&D into the production process.

  3. #293
    Join Date
    Dec 2008
    Location
    Southport, UK
    Posts
    2,746

    Default

    Quote Originally Posted by Solarfire View Post
    Yeah Doc, I'm with Terex-demag for 15 years now in R&D and production control/Testing. I know the software you'r talking about but I don't know how it is distributed. I'll check into it. It's actually more of a costomer tool. I take it you know a little about cranes? I do software, electroncis and testing here for mainly mobile telescopic cranes from 40-1000t. Bringing the R&D into the production process.
    Yeah, I'm a contracts manager for a building company, but I'm also one of the our company's two crane APs

    http://www.photonlexicon.com/forums/...ighlight=crane
    http://img62.imageshack.us/img62/3985/laser.gif

    Doc's website

    The Health and Safety Act 1971

    Recklessly interfering with Darwin’s natural selection process, thereby extending the life cycle of dim-witted ignorami; thus perpetuating and magnifying the danger to us all, by enabling them to breed and walk amongst us, our children and loved ones.





  4. #294
    Join Date
    Jan 2010
    Posts
    24

    Default

    Quote Originally Posted by dnar View Post
    It may come down to hardware integration of the sense signal using an R/C network.

    For now, I have implemented integration of 500Hz current sampling and will take it from there once I get a hardware test platform. And there lies the problem, sampling a 100kHz PWM current signal at 500Hz is just plain wrong! Hello aliasing errors!

    I do like your idea of a POST (power on self test) current calibration run.

    BTW, I just realised we have no protection for the MCU should the sense signal exceed 5V, which it could in a TEC short circuit condition (assuming the 12v supply can deliver the current)... We should add a series resistor on the sense line and a diode to clamp the ADC input at 5V maximum (plus diode Vfwd).

    Using an RC filter/integrator on the current sense line seems to be the way the app note and other designs seem to work. Shouldnt be too hard to whip something up either passively, or using the other half of the LT1013 (used for the optional NTC output voltage at the moment). Adding diode clamping would also be trivial in this case. By using an op-amp, the roll-off can be improved, for better antialiasing and thus higher sample rates, but I suspect I am stating the obvious

    Cheers,

    Pete

  5. #295
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    3,734

    Default

    Quote Originally Posted by ogoun View Post
    Using an RC filter/integrator on the current sense line seems to be the way the app note and other designs seem to work. Shouldnt be too hard to whip something up either passively, or using the other half of the LT1013 (used for the optional NTC output voltage at the moment). Adding diode clamping would also be trivial in this case. By using an op-amp, the roll-off can be improved, for better antialiasing and thus higher sample rates, but I suspect I am stating the obvious

    Cheers,

    Pete
    Hi Pete, you all agreed mate.
    This space for rent.

  6. #296
    Join Date
    Jun 2010
    Location
    Zweibrücken, Germany
    Posts
    605

    Default

    OK..I'm still majorly missing something here. Looking at the datasheet, were seening that the current sens is actually part of the current running thru the load, in this case a motor as we can tell by the slight saw tooth shaped signal. Meaning the sens signal is effected by the load, right?? In our case our sens signal is allready being filterd thru our LC filter, right????

  7. #297
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    3,734

    Default

    Quote Originally Posted by Solarfire View Post
    OK..I'm still majorly missing something here. Looking at the datasheet, were seening that the current sens is actually part of the current running thru the load, in this case a motor as we can tell by the slight saw tooth shaped signal. Meaning the sens signal is effected by the load, right?? In our case our sens signal is allready being filterd thru our LC filter, right????
    Nope. Current sense is on the input side of the L/C LPF, which is is going to reflect a completely different current waveform than is present on the TEC side of the LPF!

    Don't fret, we'll sort it once the hardware is here.
    This space for rent.

  8. #298
    Join Date
    Jun 2010
    Location
    Zweibrücken, Germany
    Posts
    605

    Default

    Quote Originally Posted by dnar View Post
    Nope. Current sense is on the input side of the L/C LPF, which is is going to reflect a completely different current waveform than is present on the TEC side of the LPF!

    Don't fret, we'll sort it once the hardware is here.
    OK. This should work..

    All the parts are here just waiting on the PCB's...
    Attached Thumbnails Attached Thumbnails MCUTEC-Controller ATtiny24 V1.00.pdf  


  9. #299
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    3,734

    Default

    Quote Originally Posted by Solarfire View Post
    OK. This should work..

    All the parts are here just waiting on the PCB's...
    Hi mate. I have never used zeners for this type of application, rather a diode tied to VCC and current limit resistor (R101).

    Also, your circuit provides no control of the capacitor charge time constant. Are you considering your design as a current to voltage integrator? If so, the 4k3 would not be necessary as it's only function was to convert I to V.

    I think the below is what is needed, I calculated the R/C time constant of R100/C100 for 0.022mS (PWM f / 2.5 = 40kHz).

    Click image for larger version. 

Name:	Sense Integrator.png 
Views:	214 
Size:	6.6 KB 
ID:	23799


    What do you think?
    This space for rent.

  10. #300
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    3,734

    Default

    If anyone is interested, here is the program c file for V1 hardware (header files not shown). Still not complete, only current limiting omitted until I play with the hardware.

    Code:
    /*
    Project: Solar fire-n-ice: An advanced bipolar PID software controller for Peltier devices.
    File: main.c - Main Program.
    Hardware platform: Atmel ATTiny84 MCU 
    Hardware version:  1.xx
    Hardware developers: 
    Frank Hill (Solarfire) VooDooI@online.de
    Wayne Osborn (dnar) wayne.osborn@dnaresearch.com.au
    Credits: This is a Photonlexicon community project http://photonlexicon.com
    
    @author Wayne Osborn wayne.osborn@dnaresearch.com.au, Copyright (C) 2011.
      
    @see The GNU Public License (GPL)
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    
    // ***************************************************************
    // Includes
    // ***************************************************************
    #include "main.h"
    #include "stdlib.h"
    #include "avr/eeprom.h"
    #include "avr/io.h"
    #include "avr/interrupt.h"
    #include "avr/wdt.h"
    
    #define _VERSION      0x0100
    
    // ***************************************************************
    // Global variables
    // ***************************************************************
    float        P_Term;                // (P) Proportional term
    float        I_State;            // (I) Integral running state
    float        I_Term;                // (I) Integral term
    float        D_Term;                // (D) Derivitive term
    float        P_Gain;                // Proportional gain
    float        I_Gain;                // Integral gain
    float        D_Gain;                // Deriviative gain
    float        PID_Gain;            // Master PID Gain (pot)
    int16_t        iError;                // Error value
    uint16_t    uiLastInput;        // Previous error value
    uint16_t    uiNTC;                // NTC raw ADC value
    uint16_t    uiSetPoint;            // Setpoint as ADC value
    int16_t        iPV;                // Process variable (PID output)
    uint16_t    uiISetPoint;        // Current Limit Set Point
    uint16_t    uiSparePot;            // Spare pot value
    uint16_t    uiCurrent;            // Bridge current 
    uint16_t    uiTimerPID;            // PID Timer value
    uint16_t    uiTimerInhibit;        // Inhibit Timer value
    uint16_t    uiTimerReadPots;    // Read physical potentiometers timer
    uint16_t    uiTimerISense;        // Current sense timer
    uint16_t    uiTimerStatus;        // Status LED update timer
    uint8_t        uiTimerPIDInt;        // PID Timer timeout flag
    uint8_t        uiTimerInhibitInt;    // Inhibit timer timeout flag
    uint8_t        uiTimerPotsInt;        // Read pots timer timeout flag
    uint8_t        uiTimerISenseInt;    // Current sense timer timeout flag
    uint8_t        uiTimerStatusInt;    // Status LED timer timout flag
    
    // ***************************************************************
    // Timer 1 overflow interrupt service routine (1002Hz) creating several synthesised timers
    // ***************************************************************
    ISR(TIM1_OVF_vect)
    {       
        TCNT1 = _TIMER1_LOAD;
        
        // ***************************************************************
        // PID Timer (20mS)
        // ***************************************************************
        if (uiTimerPID) uiTimerPID--;
        else 
        {
            uiTimerPID = TIMER_PID;
            uiTimerPIDInt = TRUE; 
        }
    
        // ***************************************************************
        // Read Potentiometers Timer (1000mS)
        // ***************************************************************
        if (uiTimerReadPots) uiTimerReadPots--;
        else 
        {
            uiTimerReadPots = TIMER_POTS;
            uiTimerPotsInt = TRUE; 
        }
    
        // ***************************************************************
        // Current Sense Timer (40mS)
        // ***************************************************************
        if (uiTimerISense) uiTimerISense--;
        else 
        {
            uiTimerISense = TIMER_ISENSE;
            uiTimerISenseInt = TRUE; 
        }
    
        // ***************************************************************
        // Inhibit Timer (1000mS)
        // ***************************************************************
        if (uiTimerInhibit) uiTimerInhibit--;
        else 
        {
            uiTimerInhibit = TIMER_INHIBIT;
            uiTimerInhibitInt = TRUE; 
        }
    
        // ***************************************************************
        // Status Timer (250mS)
        // ***************************************************************
        if (uiTimerStatus) uiTimerStatus--;
        else 
        {
            uiTimerStatus = TIMER_STATUS;
            uiTimerStatusInt = TRUE; 
        }
    } 
    
    // ***************************************************************
    // Program and MCU initialisation
    // ***************************************************************
    void init(void)
    {
        // Setup physical port direction
        DDRA = PORT_A_DIR;    
        DDRB = PORT_B_DIR;    
    
    
        // Crystal Oscillator division factor
        CLKPR = 0x00;    // No divisor, run at 20MHz
    
        //Analog Comparator Control and Status Register
        ACSR  = 0b10000000;        // No comparator
    
        // ADC Control and Status Register A
        ADCSRA = 0b10000111;    // ADC Prescaler = 128
    
        // ADC Control and Status Register B
        ADCSRB = 0b00000000;            
                 
        // Disable digital input buffers on utilised ADC channels                       
        DIDR0 = 0b10001111;  
        
        // Timer/Counter Control Register A (PWM control)
        TCCR0A = 0b10000111;    // Fast PWM on OC0A, Set OC0A on Compare Match, count down from OCR0A to 0
        OCR0A = 0x00        ;    // Initialise to 0% PWM
        
    
        // Timer/Counter Control Register B (Timer with interrupts)
        TCCR0B  = 0b00000100;   // CPU Clock = 20MHz, prescaler = 256; 
        TCNT0   = _TIMER1_LOAD; // Counter load value
        
        // General Interrupt Mask Registe
        GIMSK   = 0x00;         // No external interrupts
    
        // MCU Control Register
        MCUCR   = 0x00;                 
    
        // Timer/Counter 0 Interrupt Mask Register
        TIMSK0  = 0x01;                   // Timer/Counter0 Overflow Interrupt Enable
    
        // Watchdog Timer initialization
        wdt_enable(WDTO_1S);
     
         // Initialise program variables
        iError = 0;  
        uiLastInput = 0;  
        iPV = 0;
        
        // Enable interrupts
        sei();
    }
    
    // ***************************************************************
    // Initiate an ADC sample for a specified ADC channel and return the ADC result
    // ***************************************************************
    uint16_t Read_ADC_Sensor(uint8_t Channel)
    {
        ADMUX = Channel;  
        SETBIT(ADCSRA,ADSC);
        //Wair for ADC to be ready
        while (bit_is_clear(ADCSRA,ADIF));
                
        //Read the ADC
        SETBIT(ADCSRA,ADIF);
        return ADCW;  
    }
    
    // ***************************************************************
    // PID loop update processing
    // ***************************************************************
    float UpdatePID(uint16_t uiTarget, uint16_t uiInput)
    {
        float WindupGaurd;
    
        // Calculate the error 
        iError = uiInput - uiTarget;    
            
        // Update the Proportional term
        P_Term = P_Gain * iError;
    
        // Update the Integral term with windup protection
        I_State += iError;
        WindupGaurd = WINDUP_GUARD_GAIN / I_Gain;  
    
        if (I_State > WindupGaurd) I_State = WindupGaurd;
        else if (I_State < -WindupGaurd) I_State = -WindupGaurd;
        I_Term = I_Gain * I_State;
    
        // Update the Derivative term
        D_Term = (D_Gain * (uiInput - uiLastInput));
        uiLastInput = uiInput;                
    
        // Now return the PID result
        return  P_Term + I_Term - D_Term;
    }
    
    // ***************************************************************
    // The main loop. All processing is timer based
    // ***************************************************************
    int main(void)
    {
        init();    // Program initialisation
               
        while (TRUE)
         {
            // ***************************************************************
            // PID Update Timer timeout
            // ***************************************************************
            if (uiTimerPIDInt)    
             {       
                uiTimerPIDInt = FALSE;
                // Read the Sensor ADC
                uiNTC = 1023 - Read_ADC_Sensor(ADC_TSENSE); // Convert the temperature sample from 0..1023 to 1023.00 as the sensor slope is inverted.
                // Update the PID loop
                iPV = UpdatePID(uiSetPoint, uiNTC);
    
                // **** Current Limiting to go Here ****
                // Removed until hardware performance is terermined
                // *************************************
                if (iPV > 0) SETBIT(PORT_OUT, TEC_DIR);        // Positive PV, set direction control
                else CLRBIT(PORT_OUT, TEC_DIR);                // Negative PV, clear direction control
                OCR0A = abs(iPV);                            // Set the PWM to the absolute Process Value
            }     
    
            // ***************************************************************
            // LD-Inhibit Timer timeout
            // ***************************************************************
            if (uiTimerInhibitInt)    
            {              
                //Reset watchdog
                wdt_reset(); 
                uiTimerInhibitInt = FALSE;
                // Update the Inhibit output if out of range 
                 if ((uiNTC >= (uiSetPoint - INHIBIT_RANGE)) && (uiNTC <= (uiSetPoint + INHIBIT_RANGE))) 
                {
                    // Within +/- 2.5c enable laser modulation
                    SETBIT(PORT_OUT, LD_INHIBIT);
                }
                else
                {
                    CLRBIT(PORT_OUT, LD_INHIBIT);
                }
            }     
    
            // ***************************************************************
            // Read Set Points Timer timeout
            // ***************************************************************
            if (uiTimerPotsInt)    
            {       
                uiTimerPotsInt = FALSE;
                // Read the Tuning Pot ADC
                PID_Gain = Read_ADC_Sensor(ADC_TUNE);
                // Read the I Set Pot ADC
                uiSetPoint = Read_ADC_Sensor(ADC_ISET);
                // Read the T Set Pot ADC
                uiISetPoint = Read_ADC_Sensor(ADC_TSET);
            }     
            
            // ***************************************************************
            // Read Bridge Current Timer timeout
            // ***************************************************************
            if (uiTimerISenseInt)    
            {       
                uiTimerISenseInt = FALSE;
                // Read the Bridge Sense ADC
                uiCurrent = Read_ADC_Sensor(ADC_TSENSE);
            }     
    
            // ***************************************************************
            // Update Status Timer timeout
            // ***************************************************************
            if (uiTimerStatusInt)    
            {       
                uiTimerStatusInt = FALSE;
                // Update the under/over temperature LED's. 
                if (uiNTC - ADCPERC < uiSetPoint) 
                {
                    SETBIT(PORT_LED, LED_UNDER);    // Under Temp LED ON
                    CLRBIT(PORT_LED, LED_OVER);        // Over  Temp LED OFF
                }
                else if (uiNTC + ADCPERC > uiSetPoint) 
                {
                    CLRBIT(PORT_LED, LED_UNDER);    // Under Temp LED OFF
                    SETBIT(PORT_LED, LED_OVER);        // Over  Temp LED ON
                }
                else
                {
                    CLRBIT(PORT_LED, LED_UNDER);    // Under Temp LED OFF
                    CLRBIT(PORT_LED, LED_OVER);        // Over  Temp LED OFF
                }    
            } 
        }
    }
    This space for rent.

Posting Permissions

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