- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 85

Thema: RP6Control M32: Library für 8 Servos

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #11
    Neuer Benutzer Öfters hier
    Registriert seit
    16.12.2012
    Beiträge
    17

    Beitrag 8-Servo-Lib fuer das M256 WiFi - Modul

    Hier mal die 8-Servo-Lib fuer das M256 WiFi - Modul.

    Konnte es nicht lassen meinen Nick mit in den Comment-Header zu schreiben

    Hab auch noch die Comments an sich ein bisschen angepasst.

    Alle Servos koennen also an den IO_PWM/T0/T1 - Stecker angeschlossen werden:
    Code:
    Stecker IO_PWM/T0/T1
             _______
    Vdd    <-|10  9| -> Servo1
    Servo6 <-| 8  7| -> Servo2
    Servo7 <-| 6  5| -> Servo3
    Servo8 <-| 4  3| -> Servo4
    Ground <-| 2  1| -> Servo5
             -------
    Das ist nach belieben Veraenderbar.

    Und nicht vergessen: Externe Spannungsquelle fuer die Servos & die Masse dieser Quelle mit der Masse (Ground) des Roboters Verbinden!

    RP6ControlServo.c
    Code:
    // Uncommented Version of RP6ControlServo.c
    // written by Dirk / converted to WiFi Module M256 by MM2forever
    // ------------------------------------------------------------------------------------------
    // https://www.roboternetz.de/community/threads/40090-RP6Control-M32-Library-f%C3%BCr-8-Servos/page9?p=571435#post571435
    // ------------------------------------------------------------------------------------------
    
    #include "RP6M256Lib.h" 
    #include "RP6ControlServoLib.h"
    
    uint16_t pos = 0;
    uint16_t input;
    
    
    void demo(void)
    {
    
    	if (getStopwatch2() > 24) {
    			servo1_position = pos;
    			servo2_position = pos;
    			servo3_position = pos;
    			setCursorPosLCD(0, 0);
    			writeStringLCD_P("Servopos.: ");
    			writeIntegerLCD(pos, DEC);
    			writeStringLCD_P("   ");
    
    			pos++;
    			if (pos > RIGHT_TOUCH) {pos = 0;}
    			setStopwatch2(0);
    		}
    }
    
    
    int main(void)
    {  
    	initRP6M256(); 
    
    	initLCD();
    
    	showScreenLCD("################", "################");
    	mSleep(1500);
    	showScreenLCD("<<RP6  Control>>", "<<LC - DISPLAY>>");
    	mSleep(2500); 
    	showScreenLCD(" Servo - Test 1 ", "  Version 1.00  ");
    	mSleep(2500);
    	clearLCD();
    
    	setLEDs(0b111111);
    	mSleep(500);
    	setLEDs(0b000000);
    	
    	initSERVO(SERVO1 | SERVO2 | SERVO3);
    
    
    	startStopwatch2();
    	
    	while(true)  
    	{
    
    		demo();
    
    		task_SERVO();
    
    		mSleep(3);
    	}
    	return 0;
    }
    RP6ControlServoLib.c
    Code:
    /* ****************************************************************************
     *                           _______________________
     *                           \| RP6  ROBOT SYSTEM |/
     *                            \_-_-_-_-_-_-_-_-_-_/             >>> RP6 CONTROL
     * ----------------------------------------------------------------------------
     * ------------------ [c]2008/2013 - Dirk / MM2forever ------------------------
     * ****************************************************************************
     * File: RP6ControlServoLib.c
     * Version: 1.0
     * Target: RP6 CONTROL - M256 WiFi @16.00MHz
     * Author(s): Dirk, MM2forever
     * https://www.roboternetz.de/community/threads/40090-RP6Control-M32-Library-f%C3%BCr-8-Servos/page9?p=571435#post571435
     * ****************************************************************************
     * Description:
     * This is my simple RP6 Control Servo Library for up to 8 Servos.
     *
     * COMMENT: It is a good idea to use a separate power supply for the servos!
     *
     * Servo connections:
     *   SERVO1 -> PB6 (Pin 9 @ IO_PWM/T0/T1)		SERVO5 -> PD4 (Pin 1 @ IO_PWM/T0/T1)
     *   SERVO2 -> PB5 (Pin 7 @ IO_PWM/T0/T1)		SERVO6 -> PK5 (Pin 8 @ IO_PWM/T0/T1)
     *   SERVO3 -> PG5 (Pin 5 @ IO_PWM/T0/T1)		SERVO7 -> PD7 (Pin 6 @ IO_PWM/T0/T1)
     *   SERVO4 -> PD6 (Pin 3 @ IO_PWM/T0/T1)		SERVO8 -> PB7 (Pin 4 @ IO_PWM/T0/T1)
     *
     * ****************************************************************************
     * ATTENTION: Stopwatch 1 is used for the servo task! Please do
     *            not use this stopwatch elsewhere in your program!
     *
     * ****************************************************************************
     * THE CHANGELOG CAN BE FOUND AT THE END OF THIS FILE!
     * ****************************************************************************
     */
     
    /*****************************************************************************/
    // Includes:
    
    #include "RP6ControlServoLib.h"
    
    /*****************************************************************************/
    // Variables:
    
    uint8_t usedservos;
    uint8_t servo_on = false;
    
    uint16_t impulselength1 = 0;
    uint16_t impulselength2 = 0;
    uint16_t impulselength3 = 0;
    uint16_t impulselength4 = 0;
    uint16_t impulselength5 = 0;
    uint16_t impulselength6 = 0;
    uint16_t impulselength7 = 0;
    uint16_t impulselength8 = 0;
    
    volatile uint16_t intcounter = 0;
    
    /*****************************************************************************/
    // Functions:
    
    /**
     * INIT SERVO
     *
     * Call this once before using the servo function.
     * Timer 1 is configured to work in "Clear Timer On
     * Compare Match Mode" (CTC). So no PWM is generated!
     * The timer runs on a fixed frequency (100kHz).
     *
     * Input:  Servos -> Used Servos
     *         Examples:
     *         - initSERVO(SERVO1 | SERVO2) -> Use only Servos 1 and 2
     *         - initSERVO(SERVO1 | SERVO6) -> Use only Servos 1 and 6
     *         - initSERVO(SERVO1 | SERVO2 | SERVO8) -> Use Servos 1, 2 and 8
     *
     */
    void initSERVO(uint8_t servos)
    {
    	usedservos = servos;				// Save used Servos
    	impulselength1 = 0;
    	impulselength2 = 0;
    	impulselength3 = 0;
    	impulselength4 = 0;
    	impulselength5 = 0;
    	impulselength6 = 0;
    	impulselength7 = 0;
    	impulselength8 = 0;
    	if (servos & SERVO1) {DDRB |= OC1B_PI6; PORTB &= ~OC1B_PI6;}
    	if (servos & SERVO2) {DDRB |= OC1A_PI5; PORTB &= ~OC1A_PI5;}
    	if (servos & SERVO3) {DDRG |= IO_OC0B; PORTG &= ~IO_OC0B;}
    	if (servos & SERVO4) {DDRD |= IO_PD6_T1; PORTD &= ~IO_PD6_T1;}
    	if (servos & SERVO5) {DDRD |= IO_PD4_ICP1; PORTD &= ~IO_PD4_ICP1;}
    	if (servos & SERVO6) {DDRK |= IO_ADC13_PI21; PORTK &= ~IO_ADC13_PI21;}
    	if (servos & SERVO7) {DDRD |= IO_PD7_T2; PORTD &= ~IO_PD7_T2;}
    	if (servos & SERVO8) {DDRB |= OC0A_OCM_PI7; PORTB &= ~OC0A_OCM_PI7;}
    // -----------------------------------------------------------
    // Other possible ports for connecting Servos to RP6Control:
    //	if (servos & SERVOx) {DDRA |= ADC6; PORTA &= ~ADC6;}
    //	if (servos & SERVOx) {DDRA |= ADC7; PORTA &= ~ADC7;}
    // -----------------------------------------------------------
    	cli();
    	// Timer 1: Normal port operation, mode 4 (CTC), clk/8
    	TCCR1A =  (0 << COM1A1) 
    			| (0 << COM1A0) 
    			| (0 << COM1B1) 
    			| (0 << COM1B0) 
    		//	| (0 << FOC1A) 
    		//	| (0 << FOC1B) 
    			| (0 << WGM11) 
    			| (0 << WGM10);
    	TCCR1B =  (0 << ICNC1) 
    			| (0 << ICES1) 
    			| (0 << WGM13) 
    			| (1 << WGM12) 
    			| (0 << CS12) 
    			| (1 << CS11) 
    			| (0 << CS10);
    	TCCR1C =  0;		
    	
    	OCR1A = ((F_CPU/8/F_TIMER1)-1);	// 19 at 100kHz
    // ------------------------------------------------------
    // Possible OCR1A values (F_CPU = 16000000):
    //	OCR1A = 2000000 / F_TIMER1 - 1	// F_TIMER1  (Steps)
    //	OCR1A = 18;						// 105263Hz  (9.5us)
    //	OCR1A = 19;						// 100000Hz   (10us)
    //	OCR1A = 24;						//  80000Hz (12.5us)
    //	OCR1A = 29;						//  66667Hz   (15us)
    //	OCR1A = 34;						//  57143Hz (17.5us)
    //	OCR1A = 39;						//  50000Hz   (20us)
    // ------------------------------------------------------
    	// Enable output compare A match interrupts:
    	startSERVO();
    	sei();
    	startStopwatch1();					// Needed for 20ms pulse repetition
    }
    
    /**
     * START SERVO
     *
     * If the servo function was stopped with the
     * function stopSERVO() before, it can be
     * started again with this function.
     *
     */
    void startSERVO(void)
    {
    	TIMSK1 |= (1 << OCIE1A);
    	servo_on = true;
    }
    
    /**
     * STOP SERVO
     *
     * The servo function uses a certain amount of the
     * processor's calculating time. If the Servos are
     * not moving for a while, the Timer 1 interrupt
     * can be stopped with this function.
     *
     */
    void stopSERVO(void)
    {
    	TIMSK1 &= ~(1 << OCIE1A);
    	servo_on = false;
    }
    
    /**
     * PULSE SERVO
     *
     * This is the servo pulse generation. This function
     * must be called every 20ms (pulse repetition).
     *
     * position = 0               : Left touch
     * position = RIGHT_TOUCH     : Right touch
     * position = MIDDLE_POSITION : Middle position
     *
     * ! Please make sure in your main program, that the !
     * ! servo position values (servoX_position) don't   !
     * ! exceed RIGHT_TOUCH!!!                           !
     *
     * COMMENT: The pulses are only started here!
     *          The pulses end in the Timer 1 ISR!
     *
     */
    void pulseSERVO(void)
    {
    	if (servo_on) {
    		intcounter = RIGHT_TOUCH;		// Avoid interference of Timer 1 ISR!
    								// (Only necessary, if pulseSERVO() is called
    								//  from outside of this library!)
    		if (usedservos & SERVO1) {
    			SERVO1_PULSE_ON; impulselength1 = LEFT_TOUCH + servo1_position;}
    		if (usedservos & SERVO2) {
    			SERVO2_PULSE_ON; impulselength2 = LEFT_TOUCH + servo2_position;}
    		if (usedservos & SERVO3) {
    			SERVO3_PULSE_ON; impulselength3 = LEFT_TOUCH + servo3_position;}
    		if (usedservos & SERVO4) {
    			SERVO4_PULSE_ON; impulselength4 = LEFT_TOUCH + servo4_position;}
    		if (usedservos & SERVO5) {
    			SERVO5_PULSE_ON; impulselength5 = LEFT_TOUCH + servo5_position;}
    		if (usedservos & SERVO6) {
    			SERVO6_PULSE_ON; impulselength6 = LEFT_TOUCH + servo6_position;}
    		if (usedservos & SERVO7) {
    			SERVO7_PULSE_ON; impulselength7 = LEFT_TOUCH + servo7_position;}
    		if (usedservos & SERVO8) {
    			SERVO8_PULSE_ON; impulselength8 = LEFT_TOUCH + servo8_position;}
    		intcounter = 0;
    	}
    }
    
    /**
     * TIMER1 ISR
     *
     * In this ISR the servo pulses are finished, if the
     * correct pulse length of each servo is reached.
     *
     */
    ISR (TIMER1_COMPA_vect)
    {
    	intcounter++;
    	if (intcounter == impulselength1) {SERVO1_PULSE_OFF;}
    	if (intcounter == impulselength2) {SERVO2_PULSE_OFF;}
    	if (intcounter == impulselength3) {SERVO3_PULSE_OFF;}
    	if (intcounter == impulselength4) {SERVO4_PULSE_OFF;}
    	if (intcounter == impulselength5) {SERVO5_PULSE_OFF;}
    	if (intcounter == impulselength6) {SERVO6_PULSE_OFF;}
    	if (intcounter == impulselength7) {SERVO7_PULSE_OFF;}
    	if (intcounter == impulselength8) {SERVO8_PULSE_OFF;}
    }
    
    /**
     * SERVO TASK
     *
     * This is the servo task. The task performes the pulse repetition
     * with the help of a stopwatch.
     * At the next call of the servo task (earliest about 3ms after the
     * last servo pulse generation) the compare A match interrupt will
     * be disabled to reduce the interrupt load. It will be enabled
     * again after the next pulseSERVO() function call.
     *
     */
    void task_SERVO(void)
    {
    	if (getStopwatch1() > 2) {TIMSK1 &= ~(1 << OCIE1A);}
    	if (getStopwatch1() > PULSE_REPETITION) { // Pulse every ~20ms
    		pulseSERVO();					// Servo pulse generation
    		if (servo_on) {TIMSK1 |= (1 << OCIE1A);}
    		setStopwatch1(0);
    	}
    }
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.0 (initial release) 31.12.2008 by Dirk
     *
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // EOF
    RP6ControlServoLib.h
    Code:
    /* ****************************************************************************
     *                           _______________________
     *                           \| RP6  ROBOT SYSTEM |/
     *                            \_-_-_-_-_-_-_-_-_-_/             >>> RP6 CONTROL
     * ----------------------------------------------------------------------------
     * ------------------ [c]2008/2013 - Dirk / MM2forever ------------------------
     * ****************************************************************************
     * File: RP6ControlServoLib.h
     * Version: 1.0
     * Target: RP6 CONTROL - M256 WiFi @16.00MHz
     * Author(s): Dirk, MM2forever
     * https://www.roboternetz.de/community/threads/40090-RP6Control-M32-Library-f%C3%BCr-8-Servos/page9?p=571435#post571435
     * ****************************************************************************
     * Description:
     * This is the RP6ControlServoLib header file.
     * You have to include this file, if you want to use the library
     * RP6ControlServoLib.c in your own projects.
     *
     * ****************************************************************************
     * THE CHANGELOG CAN BE FOUND AT THE END OF THIS FILE!
     * ****************************************************************************
     */
     
    /*****************************************************************************/
    // Includes:
    
    								// The Control M256 Library. 
    #include "RP6M256Lib.h"			// Always needs to be included!
    
    /*****************************************************************************/
    // Defines:
    
    // Servo constants:
    #define SERVO1				0b00000001
    #define SERVO2				0b00000010
    #define SERVO3				0b00000100
    #define SERVO4				0b00001000
    #define SERVO5				0b00010000
    #define SERVO6				0b00100000
    #define SERVO7				0b01000000
    #define SERVO8				0b10000000
    
    // Servo movement limits (depending on servo type):
    // Standard Servos need an impulse every 20ms (50Hz). This impulse must have
    // a length of 1ms (0.7 .. 1ms) to move the servo lever to the left touch
    // and a length of 2ms (2 .. 2.3ms) for moving it to the right touch. In the
    // middle position the servo needs an impulse length of 1.5ms (1.3 .. 1.6ms).
    // If you want to modify the following constants for a certain servo type,
    // you must adapt the LEFT_TOUCH constant first (values ~70 .. 100 = ~0.7 ..
    // 1ms at 100kHz) by using a servo position value (servoX_position) of zero.
    // After that you have two "screws" to adjust the servo movement limits:
    // First you may change the RIGHT_TOUCH constant. If you choose a higher
    // value than 255, you will use 16-bit values. Higher values mean a longer
    // impulse length, but longer impulses than 2.3ms do not make sense.
    // Second you may alter the Timer 1 frequency constant (F_TIMER1).
    // A higher frequency leads to smaller steps of the servo movement. This of
    // course reduces the impulse length and may be compensated again by a higher
    // RIGHT_TOUCH constant. As a possible range of Timer 1 frequency values you
    // may use 50kHz (20us) .. 105.263kHz (9.5us).
    // HINT: If you alter F_TIMER1, you'll have to adapt LEFT_TOUCH and
    //       RIGHT_TOUCH again as you can see in the following table!
    //     Steps ->		9.5		10		12.5	15		17.5	20    [us]
    //  ------------------------------------------------------------------
    //  LEFT_TOUCH		74		71		57		47		41		35
    //  RIGHT_TOUCH		169		162		129		107		92		80
    //  F_TIMER1		105263	100000	80000	66667	57143	50000 [Hz]
    #define LEFT_TOUCH			71			// Left servo touch      (~0.7ms)
    #define RIGHT_TOUCH			162			// Right servo touch     (~2.3ms)
    #define MIDDLE_POSITION		(RIGHT_TOUCH / 2) // Middle position (~1.5ms)
    #define PULSE_REPETITION	17			// Pulse repetition freq. (~50Hz)
    #define F_TIMER1			100000		// Timer 1 frequency     (100kHz)
    
    // Servo ports:
    #define SERVO1_PULSE_ON		(PORTB |= OC1B_PI6)	// PB6
    #define SERVO1_PULSE_OFF	(PORTB &= ~OC1B_PI6)
    #define SERVO2_PULSE_ON		(PORTB |= OC1A_PI5)	// PB5
    #define SERVO2_PULSE_OFF	(PORTB &= ~OC1A_PI5)
    #define SERVO3_PULSE_ON		(PORTG |= IO_OC0B)	// PG5
    #define SERVO3_PULSE_OFF	(PORTG &= ~IO_OC0B )
    #define SERVO4_PULSE_ON		(PORTD |= IO_PD6_T1)// PD6
    #define SERVO4_PULSE_OFF	(PORTD &= ~IO_PD6_T1)
    #define SERVO5_PULSE_ON		(PORTD |= IO_PD4_ICP1)//PD4
    #define SERVO5_PULSE_OFF	(PORTD &= ~IO_PD4_ICP1)
    #define SERVO6_PULSE_ON		(PORTK |= IO_ADC13_PI21)// PK5
    #define SERVO6_PULSE_OFF	(PORTK &= ~IO_ADC13_PI21)
    #define SERVO7_PULSE_ON		(PORTD |= IO_PD7_T2) // PD7
    #define SERVO7_PULSE_OFF	(PORTD &= ~IO_PD7_T2)
    #define SERVO8_PULSE_ON		(PORTB |= OC0A_OCM_PI7)// PB7
    #define SERVO8_PULSE_OFF	(PORTB &= ~OC0A_OCM_PI7)
    // -----------------------------------------------------------
    // Other possible ports for connecting Servos to RP6Control:
    //#define SERVOx_PULSE_ON		(PORTA |= ADC6)		// PA6
    //#define SERVOx_PULSE_OFF	(PORTA &= ~ADC6)
    //#define SERVOx_PULSE_ON		(PORTA |= ADC7)		// PA7
    //#define SERVOx_PULSE_OFF	(PORTA &= ~ADC7)
    // -----------------------------------------------------------
    
    /*****************************************************************************/
    // Variables:
    
    uint16_t servo1_position;		// Servo 1 position [0..RIGHT_TOUCH]
    uint16_t servo2_position;		// Servo 2 position [0..RIGHT_TOUCH]
    uint16_t servo3_position;		// Servo 3 position [0..RIGHT_TOUCH]
    uint16_t servo4_position;		// Servo 4 position [0..RIGHT_TOUCH]
    uint16_t servo5_position;		// Servo 5 position [0..RIGHT_TOUCH]
    uint16_t servo6_position;		// Servo 6 position [0..RIGHT_TOUCH]
    uint16_t servo7_position;		// Servo 7 position [0..RIGHT_TOUCH]
    uint16_t servo8_position;		// Servo 8 position [0..RIGHT_TOUCH]
    
    /*****************************************************************************/
    // Functions:
    
    void initSERVO(uint8_t servos);
    void startSERVO(void);
    void stopSERVO(void);
    void pulseSERVO(void);
    void task_SERVO(void);
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.0 (initial release) 31.12.2008 by Dirk
     *
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // EOF
    Geändert von radbruch (12.02.2013 um 20:48 Uhr) Grund: Link auf Beitrag in den Quellcode eingefügt. (soll nur 'ne Anregung sein)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen