Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo mit PCF8574 ansteuern
Hallo,
ich weiß, dass es zum Thema Servoansteuerung schon so viele Threads gibt, nur leider hab ich keinen gefunden wo der Servo mit nem PCF8574 angesteuert wird, und auch keinen wo meine Probleme behandelt werden.
Also ich hab einen RP6 ohne M32 mit einer Erweiterungsplatine wo der PCF8574A drauf ist, andessen seinen I/O Ports die Signalservoleitung liegt.
Mein momentaner Code sieht so aus:
//Servoansteuerungs Test
#include "RP6RobotBaseLib.h"
#include "RP6I2CmasterTWI.h"
#define PCF8574_Schreiben 0b01110000
void ServoAnsteuern( uint8_t grad)
{
if(getStopwatch1() >= 20){ // Alle 20 ms Impuls senden
setStopwatch1(0);
I2CTWI_transmitByte(PCF8574_Schreiben, 0b00001000); // Signal auf High
sleep(grad); // Signaldauer
I2CTWI_transmitByte(PCF8574_Schreiben, 0b00000000); // Signal auf Low
}
}
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("I2C ERROR - TWI STATE: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
int main(void)
{
initRobotBase();
I2CTWI_initMaster(100);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
startStopwatch1();
uint8_t grad = 15; // = 1,5ms -> normalerweise Mittelstellung
while(true)
{
ServoAnsteuern(grad);
task_I2CTWI();
}
return 0;
}
Momentan eben erst mal nur zum Testen, es soll eben nur in Mittelstellung gefahren werden und gehalten werden.
Nun meine Probleme:
1. Einerseits hab ich einen TOP LINE MINI SERVO Y-3009 von Conrad (http://www.conrad.de/ce/de/product/209089/TOP-LINE-MINI-SERVO-Y-3009/SHOP_AREA_19788&promotionareaSearchDetail=005) drangehängt. Dieser fährt zwar auf die Position zittert aber ständig + - 10grad hin und her.
2.Andererseits hab ich einen TOP-LINE STANDARD SERVO RS 2 JR ebenfalls von Conrad (http://www.conrad.de/ce/de/product/233751/TOP-LINE-STANDARD-SERVO-RS-2-JR/SHOP_AREA_19788&promotionareaSearchDetail=005) drangehängt, dieser fährt allerdings nur an den rechten Anschlag und drückt weiter (Ich hab auch schon alle möglichen Impulsdauern ausprobiert, zwichen 0,1 und 10 ms - leider keine Änderung).
Vielen Dank schon jetzt für dei Antworten
MFG DERICH
radbruch
23.01.2011, 23:57
Hallo
Eine Servoansteuerung mit dem PCF8574 habe ich auch noch nicht gesehen. Ich habe aber auch noch nicht danach gesucht. Das könnte aber grundsätzlich funktionieren.
Das Zittern könnte möglicherweise von der Sleep() /Watchdog()-Ansteuerung kommen. Hast du die Servos mal direkt an einem RP6-Ausgang angeschlossen und mit den selben Impulsen getestet?
Wenn man die Funktion I2CTWI_transmitByte() in der Datei RP6I2CmasterTWI.c betrachetet fallen gleich zu Beginn der Funktion zwei Hindernisse auf:
/************************************************** ***************************/
// Transmission functions
/**
* Transmits a single byte to a slave device. It waits until the last
* TWI operation is finished (it blocks the normal program flow!) but
* it does NOT wait until this transmission is finished!
* This allows you to perform other things while the transmission is
* in progress!
*/
void I2CTWI_transmitByte(uint8_t targetAdr, uint8_t data)
{
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
I2CTWI_delay();
TWI_msgSize = 2;
I2CTWI_buf[0] = targetAdr;
I2CTWI_buf[1] = data;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
}
Da die letzte TWI-Übertragung mindestens vor servopos (0,5-2ms?) stattgefunden hat, würde ich diese Zeile erstmal ausblenden:
while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI();
Ebenso sollte man dann wohl diese Zeile auskommentieren:
I2CTWI_delay();
Besser als Auskommentieren wäre vielleicht das:
while(true)
{
if(getStopwatch1() >= 20){ // Alle 20 ms Impuls senden
setStopwatch1(0);
TWI_msgSize = 2;
I2CTWI_buf[0] = PCF8574_Schreiben;
I2CTWI_buf[1] = 0b00001000;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
//task_I2CTWI();
sleep(grad); // Signaldauer
TWI_msgSize = 2;
I2CTWI_buf[0] = PCF8574_Schreiben;
I2CTWI_buf[1] = 0b00000000;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
//task_I2CTWI();
}
}
return 0;
(Ungetestet und nicht kompiliert)
Wenn das überhaupt nicht funktionieren sollte, fehlt vermutlich task_I2CTWI(); Das solltest du aber meiden, weil das Tasksystem unkontrollierbare Zeitverzögerungen erzeugt. Hier bliebe dann nur noch die direkte Ansteuerung der TWI-Funktionen des Mega32 ohne das Tasksystem des RP6.
Gruß
mic
Also erst mal Vielen Dank !! Mein Mini Servo zuckt nicht mehr!
Wenn ich es allerdings so machen will anstatt in der libary:
//Servoansteuerungs Test
void senden(uint8_t adresse, uint8_t daten){
TWI_msgSize = 2;
I2CTWI_buf[0] = adresse;
I2CTWI_buf[1] = daten;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
//task_I2CTWI();
}
void ServoAnsteuern( uint8_t grad)
{
if(getStopwatch1() >= 20){ // Alle 20 ms Impuls senden
setStopwatch1(0);
senden(PCF8574_Schreiben, 0b00001000); // Signal auf High
sleep(grad); // Signaldauer
senden(PCF8574_Schreiben, 0b00000000); // Signal auf Low
}
}
}
... bekomme ich einen Fehler:
PCF8574.c:9: error: 'TWI_msgSize' undeclared (first use in this function)
PCF8574.c:9: error: (Each undeclared identifier is reported only once
PCF8574.c:9: error: for each function it appears in.)
PCF8574.c:10: error: 'I2CTWI_buf' undeclared (first use in this function)
Finde allerdings die Deklarationen auch in der libary nicht.
Allerdings hab ich immer noch das Problem dass meine anderen Servos nur nach links überdrehen und ich weiß nicht warum :(
Kaputt können sie eigtl nich sein weil ich hab schon 3 neue ausprobiert und bei allen das selbe :(
MFG DERICH
radbruch
24.01.2011, 16:27
Hallo
Die TWI-Variablen werden in RP6I2CmasterTWI.c definiert. Normalerweise sollte man die dann mit "extern" importieren können, aber ich kanns nicht. Auch nicht, wenn man das "static" bei den Definitionen entfernt: http://openbook.galileocomputing.de/c_von_a_bis_z/009_c_funktionen_012.htm
//Servoansteuerungs Test
#include "RP6RobotBaseLib.h"
#include "RP6I2CmasterTWI.h"
#include "RP6I2CmasterTWI.c" // oje :(
#define PCF8574_Schreiben 0b01110000
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("I2C ERROR - TWI STATE: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
void senden(uint8_t adresse, uint8_t daten)
{
TWI_msgSize = 2;
I2CTWI_buf[0] = adresse;
I2CTWI_buf[1] = daten;
TWI_statusReg.all = 0;
TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(0<<TWEA)|(1<<TWSTA)|(0<<TWSTO);
task_I2CTWI();
}
void ServoAnsteuern( uint8_t grad)
{
if(getStopwatch1() >= 20) // Alle 20 ms Impuls senden
{
setStopwatch1(0);
senden(PCF8574_Schreiben, 0b00001000); // Signal auf High
sleep(grad); // Signaldauer
senden(PCF8574_Schreiben, 0b00000000); // Signal auf Low
}
}
int main(void)
{
uint8_t grad = 15; // = 1,5ms -> normalerweise Mittelstellung
initRobotBase();
I2CTWI_initMaster(100);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
startStopwatch1();
while(true)
{
ServoAnsteuern(grad);
}
return 0;
}
Das kann ich wenigstens Fehler- und Warnungsfrei übersetzen. Im makefile muss man dann natürlich RP6I2CmasterTWI.c rausschmeisen.
Gruß
mic
komisch :( laut buch müsst es ja funktionieren
und wenn ich die .c datei importier und aus dem make raus hau geht gar nix mehr :(
aber das ist ja nicht so schlimm so lang ich nichts anderes außer servos an i2c ran häng.
Aber hat vll wer ne idee fürs andere Prob?
MFG DERICH
radbruch
24.01.2011, 18:01
Das JR2 ist eine ganz andere Leistungsklasse als das Miniservo, es benötigt deshalb vermutlich auch deutlich mehr Strom. Möglicherweise bricht dann die Versorgungsspannung des Servos ein.
wenn die spannnung einbrechen würde, würde er ja nicht weiter nach rechts drehen
außerdem hab ich für dei Servos einen extra 2A spannungsregler und da hängt momentan eben nur 1 servo dran
radbruch
24.01.2011, 18:54
Zucken die Servos beim Einschalten nicht auch immer in die selbe Richtung?
Egal, vielleicht hilft ein PullUp am Ausgang des PCF8574. Möglicherweise reicht die Power (100µA?) nicht für ein sauberes Servosignal:
7.3 Quasi-bidirectional I/Os
A quasi-bidirectional I/O can be used as an input or output
without the use of a control signal for data direction
(see Fig.15). At power-on the I/Os are HIGH. In this mode
only a current source to VDD is active. An additional strong
pull-up to VDD allows fast rising edges into heavily loaded
outputs....
Gruß
mic
ja alle Servos (auch der kleine) zuckt beim einschalten nach rechts (was hat das damit zu tun?)
übrigens bringt der ausgang 300uA, und das dürfte für ein Servo Signal eigtl schon reichen, außerdem müsste die leistung auf dem signal ja eigtl unabhängig davon sein ob der servo strak oder schwach ist, weil ja die elektronik im endefekt die selbe ist
MFG DERICH
radbruch
24.01.2011, 19:49
Hallo
Ausgangsstrom ist 30-300µA laut Tabelle Seite 15, im vereinfachten Schema auf Seite 9 ist allerdings 100µA angegeben. Kannst dir wohl selbst raussuchen, was nun stimmt.
...wenn die spannnung einbrechen würde, würde er ja nicht weiter nach rechts drehen...
ja alle Servos (auch der kleine) zucken beim Einschalten nach rechts (was hat das damit zu tun?)Drehen sie nach rechts, weil das Signal es befiehlt, oder weil sie nach einem Spannungseinbruch immer wieder eingeschaltet werden?
Wenn beide Servotypen "im Endeffekt" dieselbe Elektronik hätten, würde es wohl mit beiden Servotypen funktionieren ;)
Gruß
mic
also sie drehen nicht wegen der software nach rehct weil des tun sie ja dann wenn ich den schalter umleg aber des prog ja noch gar net starte
kann vll vom booten vom PCF kommen .. ka
brauch ich vll irgend nen vorweiderstand vorm servo oder so?
also nochmal von Vorn :
-ich hab 2 verschiedene arten von Servos wie oben beschrieben)
-beide reagieren an einem servo tester gleich
-spannung am robo bricht nicht zusammen (hab ich gemessen)
-großer überdreht einfach nach rechts
-kleiner ist normal steuerbar
-ich hab schon vorwiederstände am signal versucht (100 , 1k -> keine Veränderung bei beiden, 4,7k -> keiner reagiert überhaupt mehr (fast wie vermutet))
Was soll ich noch tun :(
MFG DERICH
Also erst mal Danke radbruch!!
Du kontest mein 1. Prob lösen!!
Fürs 2. hab ich im richtigen Forum ein neues Thema gemacht.(https://www.roboternetz.de/phpBB2/viewtopic.php?p=535786#535786)
MFG DERICH
Ok ich hab es selber gelöst!!! Trotzdem Danke !!
lösung:
Mein Steuer Ic (pcf8574) hat am ausgan nur 0,3mA gebracht und das hat zwar für den kleinen greciht aber für den großen nicht!
Also hab ich einfach einen Transitor zwichengeschalten d.h. ic an basis, emiter an plus und collector an servo, Und schon gings!
MFG DERICH
Hallo
Darüber hatten wir ja schon gesprochen. Hast du es mit dem PullUp auch versucht?
Gruß
mic
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.