PIC och PWM

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

PIC och PWM

Inlägg av wolie »

Tänkte koppla in en servo till USB experimentkortet k8055. k8055 ger pwm med 20mS bredd.
Nedan är en krets med en PIC 16F84 som driver en servo via serieporten.
http://www.rentron.com/images/serservo.gif
Går det ätt göra så att PWM:en från k8055 läggs på RB0 och att man sedan 'fångar' upp frekvensen och använder den för att sända 1,0-2,0 mS ut på RB1?

Skrev lite pseudo kod i en mall nedan.
Tror ni att detta över huvud taget är genomförbart?

Kod: Markera allt

  symbol pos = b2                ' Position storage
  symbol count = b4             ' Count storage
  dim j,j2 as byte

  start:           
    wait until PORTB.0 = 1 then     'pseudo kod
    j = timeinns(now)
    wait until PORTB.0 = 0 then   
    j2 = timeinns(now)
    (j2-j)*något=pos    
  goto move                             'end pseudo kod

  move:
  for count = 0 to 40               
    pulsout PORTB.1,pos            ' Send servo 1, to position# ?
    pause 20                        ' Timing delay
  next count                          ' Do it again until count = 40
  goto start                            ' Return and wait for more input
Tack,

EDIT:
Undrar också om möjligheterna att använda en ne555 som man då styr med k8055. Alltså att ersätta VR1 med PWM i denna kretsen:
http://members.tripod.com/Sarconastic/circuitse.gif
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

på min hemsida, under "Freebies" finns det ett projekt som medger att man kan styra 13 servos med en PIC16F628A via en serieport. Det finns källkod och allt och tydligen finns det folk som faktisk har tillverkad den och varit belåtna.

Jag undviker helst allt Vellerman men det GÅR nog att göra det du vill men det är en del mer besvärligt i mina ögon.
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

Jo, den du gjort verkar mycket bra. Tyvärr har jag bara en serieport och den är upptagen.
Hur funkar det med ADC på PIC? Hur snabbt reagerar den, klarar den PWM? Om inte kanske man kan använda DAC->PIC?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Vad är det du vill åstadkomma?

Vill du ha ett potentiometer där du kan ställa servons position på eller vad?
Användarvisningsbild
Fagge
Inlägg: 3930
Blev medlem: 27 maj 2003, 13:59:51
Ort: Blekinge

Inlägg av Fagge »

Det verkar vara många som har missat att forumet har en Mikroprocessor kategori!. :?
Tråd flyttad...
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

Trodde det framgick. Jag vill koppla en PIC till Velleman k8055 experimentkort genom antingen utgångarna DAC eller PWM. PIC:en i sin tur styr då servot.

Altså:
USB--Velleman--DAC--> ADC--PIC--PWM--> SERVO
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Hur funkar det med ADC på PIC?

Bra.

> Hur snabbt reagerar den

Enligt databladet, så klart...
Det skiljer också mellan olika PIC modeller.

> klarar den PWM?

Nej. ADC'n används för att omvandla en analog spänning till ett digitalt värde.
Det har inte ett dugg med PWM att göra.

Om jag förstår rätt så vill du med K8055 generera en analog spänning
som via en extra PIC omvandlas till ett servoläge !? Jag ser inga
problem med detta.
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

Du har förstått det rätt.
Iom. att DAC på velleman kortet, enligt denna tråden: http://www.elektronikforumet.com/forum/ ... hp?t=21083 , inte orkade att leverera ström undrade jag om man kunde köra PWM till PIC:en och få den att 'tro' att strömmen är analog. (ex 50% PWM -> 2.5V)

Men det ska väl inte vara helt omöjligt att lösa med en NPN-transistor?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> inte orkade att leverera ström... ???

Hur mycket "ström" behöver du ???
Skulle inte spänningen in på en ADC på den extra PIC'en ?

> om man kunde köra PWM till PIC:en och få den att 'tro' att strömmen är analog.

Visst, det går att filtrera ner en PWM-signal till en likspänning med en R-C länk.

> Men det ska väl inte vara helt omöjligt att lösa med en NPN-transistor?

Eller med en skruvmejsel, vad vet jag... :-) :-)
Hur tror du att man ska kunna ha någon synpunkt på en "NPN-transistor"
om det inte framgår vad den ska användas till ????
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

> Hur mycket "ström" behöver du ???
I tråden jag länkade till (sista inlägget) skrev Ulltieri att strömmen inte räckte till för att driva detta kitet baserat på 16C54 från velleman k8055.

> Eller med en skruvmejsel, vad vet jag...
Om strömmen inte räcker till kanske man kan 'förstärka' strömmen med en transistor av något slag? Så jag menade...

R-C länk?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

RC-länk : http://en.wikipedia.org/wiki/RC_circuit

För övrigt hoppar jag av här.
Alldeles för mycket prylar att läsa igenom...
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

Du ska ha tack iaf. Sodjan.

Tänkte ge det hela en chans, och försöker nu porta kod för en PIC12F683 från www.flyelectric.ukgateway.net.

Gjort några ändringar nedan, men ej testat:

Kod: Markera allt

#include "12F675.H"				//PIC chip file
#include "delay_ms.h"			//Delay function used below

#pragma config = 0b.11.1100.0100//Core device configuration


//VARIABLES section 

#define LED 	GPIO.4			//LED output defined (pin3)
#define SERVO 	GPIO.5			//Servo output defined (pin2)

uns16 POT;						//Variable to represent the ADC value of the servo control pot
uns16 PULSE;					//Variable to calculate pulse width
uns16 p;						//Variable used in timers/counters

void main()
{
//Main port settings
	TRIS2 = 1;				//Sets GP2/AN2 (pin5) to be Input for pot
	TRIS4 = 0;				//Sets GP4/AN3 (pin3) to be Output for LED
	TRIS5 = 0;				//Sets GP5 (pin2) to be Output for Servo

    ANS2 = 1;					//Enables ADC port AN2 for pot control
    ANS3 = 0;					//Disables ADC port AN3 (make digital) for LED

    CMCON = 0b.111;			//Switches all 3 comparator ports off

//ADC settings (ADC needed for pot input)
    ADCON0.6 = 0;				//VCFG: Use Vdd for ADC voltage reference
    ANSEL.4 = 1;				//ADCS: Set AD Conversion Clock to Fosc/16
    ANSEL.5 = 0;				//part of above
    ANSEL.6 = 1;				//part of above
    ADCON0.7 = 1;				//ADFM: Right-justify ADC register

//Activate ADC
    ADCON0.0 = 1;				//ADON: Turn AD module ON
    ADCON0.3 = 1;				//CHS0: Select input channel to ANS2 only
    ADCON0.2 = 0;				//part of above
    ADIE = 0;					//ADC interrupts disabled

//Static Timer1 settings (use to generate high pulses)
	T1CON.1=1;					//Sets prescaler to 16

//Start low
	SERVO = 0;

//Flash LED three times on startup
	for (p=0; p<3; p++)
	{
		LED=1;
		delay_ms(250);
		LED=0;
		delay_ms(250);
	}
	LED=1;						//Leave LED on to indicate powered up


    while(1)						//Continuous loop to monitor pot and instruct servo to move
    {

	//Run ADC to convert pot position into digital
    	delay_ms(1);				//Delay for acquisition capacitor to charge
		ADIF = 0;					//Clear the ADC Complete flag
		ADCON0.1 = 1;				//GO: Start ADC acquisition
		while(ADIF==0);				//Wait for conversion to complete (become 1)

	//Determine ADC value (this is a 10bit value stored in two registers that need merging)
		POT = ADRESH;				//Copies upper 2 bits from 8bit register to 16bit
		POT = POT<<8;				//<<8 moves all bits 8 places left (hence the need for 16bits)
		POT = POT|ADRESL;			//| merges Lower 8 bits of ADRESL with upper 2

	//The calculation that follows creates a pulse width parameter 'PULSE' based on the pot position
	//With the prototype's pot, the ADC values range from 322 to 629 (measured by logging in EEPROM)
	//Goal is to make these represent 1 to 2ms (standard servo pulse widths)
	//Timer2 requires 63 for 1ms and 126 for 2ms

		PULSE = POT;				//Pick up ADC POT value
		PULSE -= 322;				//Deduct POT's lowest ADC value (bottom end)
		PULSE *= 63;				//Multiply by difference between timer values for 2 and 1ms (126-63=63)
		PULSE /= 307;				//Divide by difference between Pot upper and lower values (629-322=307)
		PULSE += 63;				//Add timer value for 1ms

	//Instruct servo to move!
		PIR1 = PULSE.low8;			//Timer 1 counts to the value set in PR2 ('period register')
									//Timer 1 can only handle 8bits; required value is within this limit
		TMR1H=0;						//Initialise Timer1

		TMR1IF = 0;					//Reset interrupt flag

		SERVO = 1;					//Go high
	    TMR1ON = 1;					//Start Timer1 (timer increments to PR2 value)
		while(TMR1IF==0);			//TMR1IF flag is set to 1 when Timer1 reaches PR2
		TMR1ON = 0;					//Stop Timer1

		SERVO = 0;					//Go low
	    delay_ms(20);				//for 20ms


	}							//end while
}								//end main


Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Inlägg av vfr »

Och vad är frågan?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> ...men ej testat:

Gör det.
wolie
Inlägg: 118
Blev medlem: 1 juli 2007, 11:07:08
Ort: Gbg

Inlägg av wolie »

vfr skrev:Och vad är frågan?
Om koden ser korrekt ut.
Skriv svar