Forum: Mikrocontroller und Digitale Elektronik 32 Servos an Atmega328


von Lukas D. (programmierer12)


Lesenswert?

Hallo allerseits,
ich habe zur Zeit ein kleines Problemchen...
Ich möchte an einem Atmega328 32 Servos betreiben. Ich habe bereits 
etwas rechachiert und bin auf das Breakout des PCA9685 von Adafruit 
gestoßen was mir aber für fast 15€ zu teuer ist und ich eigentlich einen 
Chip auf einer Platine fest einsetzen möchte. Andere Überlegung wäre 
gewesen per SoftwarePWM und MCP23017 die Servos zu steuern, nur habe ich 
da keine Beispiele oder ähnliches gefunden wie das gehen soll.
Nun die Frage: hat vielleicht jemand von euch eine Ahnung oder eine Idee 
wie ich das am einfachsten hinbekommen kann?

MFG
Lukas

von Michael (Gast)


Lesenswert?

SoftPWM und so viele Servos ist meist keine gute Idee.
Je nachdem was Dein System macht zittern die Servos wie Fliegen!

von Lukas D. (programmierer12)


Lesenswert?

Ja das dachte ich mir eigentlich schon...
Es werden maximal 4 Servos gleichzeitig angetrieben. Ich denke da dürfe 
man nicht so große Probleme mit Geschwindigkeiten bekommen.

von Harry L. (mysth)


Lesenswert?


von Robbe (Gast)


Lesenswert?

Schon mal etwas gerechnet?
Glauben hilft da nich viel.

Mit etwas Programmiergeschick wird das zeitlich völlig unkritisch sein.
Nimm einfach 2 Atmegas damit Du genug portpins hast, billiger und 
straiter gehts nicht

von Robbe (Gast)


Lesenswert?

Straight...

von Lukas D. (programmierer12)


Lesenswert?

Robbe schrieb:
> Schon mal etwas gerechnet?
> Glauben hilft da nich viel.
>
> Mit etwas Programmiergeschick wird das zeitlich völlig unkritisch sein.
> Nimm einfach 2 Atmegas damit Du genug portpins hast, billiger und
> straiter gehts nicht

Du meinst zwei Atmegas per Seriell kommunizieren lassen?

von Martin S. (led_martin)


Lesenswert?

Da der Servo-Impuls deutlich kürzer ist, als die Periodendauer, kann man 
das Ausgangssignal von einem Hardware PWM-Ausgang per Dekoder, im 
Zeitmultiplex, auf mehrere Servos verteilen. Das würde auch das Problem 
lösen, das der ATmega328 gar keine 32 Signalausgänge hat. Wobei solche 
Aufgaben mit Software-PWM durchaus lösbar sind, auch ohne Zittern der 
Servos, wenn man entsprechend gut programmieren kann. Wenn Du mit 20ms 
Periodendauer (ist ein gängiger Wert) arbeiten willst, kannst Du gerade 
so 8 Servos (max. 2,5ms Impuls) aus einem PWM-Ausgang bedienen. Die 
Arbeit auf mehrere, eventuelle recht kleine (z.B. ATtiny), 
Mikrocontroller zu verteilen, wäre vielleicht auch noch eine 
Möglichkeit.

Mit freundlichen Grüßen - Martin

von Robbe (Gast)


Lesenswert?

Lukas D. schrieb:
> Robbe schrieb:
>> Schon mal etwas gerechnet?
>> Glauben hilft da nich viel.
>>
>> Mit etwas Programmiergeschick wird das zeitlich völlig unkritisch sein.
>> Nimm einfach 2 Atmegas damit Du genug portpins hast, billiger und
>> straiter gehts nicht
>
> Du meinst zwei Atmegas per Seriell kommunizieren lassen?

Wie auch immer, die Stellwerte kommen doch irgendwo her.

von Robbe (Gast)


Lesenswert?

Das wird auch völlig trivial mit einfachen Schieberegistern 
funktionieren.
Nimm mal Papier und Bleistift zur Hand und erstelle ein Konzept.

von Dr. Sommer (Gast)


Lesenswert?

Martin S. schrieb:
> Die Arbeit auf mehrere, eventuelle recht kleine (z.B. ATtiny),
> Mikrocontroller zu verteilen, wäre vielleicht auch noch eine
> Möglichkeit.

Viel zu kompliziert. Man nimmt einfach einen Controller der genug 
Hardware PWM Channel hat, wie zB diverse STM32.

von Robbe (Gast)


Lesenswert?

Außerdem benötigt der Servo PPM nicht PWM.

Welche Plattform Du nutzt hängt von deinen Kenntnissen ab, Hardware wie 
Software.

Arduino unterstützt, meine ich, bis zu 12 Servos an beliebigen Pins.

von Lukas D. (programmierer12)


Lesenswert?

Robbe schrieb:
> Außerdem benötigt der Servo PPM nicht PWM.
>
> Welche Plattform Du nutzt hängt von deinen Kenntnissen ab, Hardware wie
> Software.
>
> Arduino unterstützt, meine ich, bis zu 12 Servos an beliebigen Pins.

Also ich denke die Hardware wäre nicht das Problem nur Software bin ich 
in c nicht grad auf der Höhe.
Noch habe ich alle Projekte mit der Arduino Plattform realisieren 
können...

von Wolfgang (Gast)


Lesenswert?

Jeweils 8 Servos kann man doch einfach bedienen, indem man eine "1" 
durch ein Schieberegister schiebt und den Abstand der Taktflanke 
entsprechend der jeweils gewünschten Servopulslänge wählt. Dann braucht 
man als µC auch keinen "100-Füßler".

von Peter D. (peda)


Lesenswert?

Wolfgang schrieb:
> indem man eine "1"
> durch ein Schieberegister schiebt

Und wenn man den Takt mit nem PWM-Pin erzeugt, hat man auch keinen 
Jitter durch andere Interrupts.

von Markus (Gast)


Lesenswert?

>Noch habe ich alle Projekte mit der Arduino Plattform realisieren
>können...
https://www.arduino.cc/en/Reference/Servo

Die Servo-Library kann scheinbar 12 Servos ansteuern. Du bräuchtest also 
3 Arduino Nanos über eine Schnittstelle verbunden.

Was spricht gegen Multiprozessing?

von Harry L. (mysth)


Lesenswert?

Markus schrieb:
> Du bräuchtest also
> 3 Arduino Nanos über eine Schnittstelle verbunden.
>
> Was spricht gegen Multiprozessing?

So einen Schwachsinn können sich auch nur "Arduidioten" ausdenken....

Die PCA9685 waren schon der richtige Ansatz.

von Markus (Gast)


Lesenswert?

>Die PCA9685 waren schon der richtige Ansatz.

Das hängt alles von dem Anspruch an den Optimierungsgrad und den genauen 
Anforderungen ab.
Zwei PCA9685 kosten ca. 30 Euro
https://www.adafruit.com/product/815
3 Arduino Nano vom Chinesen kann man für unter 10 Euro erwerben.

>So einen Schwachsinn können sich auch nur "Arduidioten" ausdenken....
Solche Sprüche lassen die Dumpfbacken (TM) im MC-Netz gerne mal los
( ist scheinbar schon seit 2006 aktiv:
Beitrag "Re: Programmierbarer Widerstand?" )

Ich weiß, bei einer Vielzahl an Lösungsmöglichkeiten eines Problems 
kommt eine Dumpfbacke schnell an die Grenzen ihres geistigen Horizonts.

von Harry L. (mysth)


Lesenswert?

Markus schrieb:
> Zwei PCA9685 kosten ca. 30 Euro

Wie kommst du da drauf?
http://www.ebay.de/itm/PCA9685-Servomotor-Driver-16-Kanal-Treiber-Modul-PWM-I2C-Arduino-Raspberry-/162533562184

Mit etwas Suche findet man die auch noch erheblich billiger.

von Jobst M. (jobstens-de)


Lesenswert?

Der 4017 ist der richtige Baustein. Mit dem wurden früher auch die 
Signale der Mehrkanalfernbedienungen auf Servos verteilt.
Mit 5 Leitungen kann man so bequem 32 Servos ansteuern.

Reset aller Bausteine bei 0, wenn die On-Zeit für Servo 1 abgelaufen 
ist, Taktimpuls und die On-Zeit für Servo 2 startet. Wenn die abgelaufen 
ist, wieder einen Taktimpuls und On-Zeit für Servo 3 startet ...
1
R ___|_______________________________________________________________
2
3
T__________|____|___|_______|______|______|____|_____________________
4
      _____
5
S1 __|     |_________________________________________________________
6
            ____
7
S2 ________|    |____________________________________________________
8
                 ___
9
S3 _____________|   |________________________________________________
10
                     _______
11
S4 _________________|       |________________________________________
12
13
S5 ...


Gruß
Jobst

von Wolfgang (Gast)


Lesenswert?

Harry L. schrieb:
> Die PCA9685 waren schon der richtige Ansatz.

8-Bit Auflösung für die Servo-Pulsbreite ist nicht so der Bringer, aber 
möglicherweise reicht das für die angedachte Anwendung.

von Lukas D. (programmierer12)


Lesenswert?

Danke schonmal für die ganzen Hilfestellungen. Ich werde jetzt erstmal 
die Möglichkeit mit dem 4017 testen und alternativ das China Board mit 
dem PCA9685 im Auge behalten.

von Zum abschreiben (Gast)


Lesenswert?


von Rangi J. (rangi)


Lesenswert?

Also ich habe 24 Servos an einem Mega8515 mit 8Mhz hängen, das geht ganz 
gut.
Ich habe die Servos erstmal in 4 Gruppen aufgeteilt. Für jede Gruppe 
werden die Werte der PWM immer neu vergleichen und gesetzt.
Dann einen Timer verwendet, der die Zeit per Output-Compare auflöst. Um 
die einzelenen Schritte auszurechnen, lasse ich den Timer alle 10µs 
einen Interrupt erzeugen. Dieser beendet dadurch einen Sleep-Befehl. Der 
Code läuft dadurch synchron.
1
    for(sd_timer=0;sd_timer<SD_TIMER_TOP;sd_timer++)   /*10µs pro loop*/
2
    {
3
      SD_SLEEP;   /*timer weckt durch interrupt*/
4
      if(sd_timer >= val0) { IO_PWM_OUT_00_DIS; } else { IO_PWM_OUT_00_EN; }
5
      if(sd_timer >= val1) { IO_PWM_OUT_01_DIS; } else { IO_PWM_OUT_01_EN; }
6
      ...
7
      if(UCSRA & (1<<RXC)) sio_in_buffer[bptr++]=UDR;   /*Schnittstelle lesen*/
In den Pausen zwischen den 4 Gruppen wird die Position der Servos neu 
berechnet und Kommunikation am laufen gehalten.
Ein paar Sachen muss man optimieren, z.B. die ISR
1
/*dieser INT reisst den µc aus dem schlaf*/
2
/*ACHTUNG !!! - Das ist eine pseudo-Interruptroutine*/
3
/*sie wird korrekt eingetragen, aber es werden keine Register gesichert*/
4
void TIMER1_COMPA_vect(void)
5
{
6
  asm("reti");
7
}

Eine andere Idee ist, wenn nicht alle Servos gleichzeitig laufen müssen, 
kann man die Servos auch nur dann anschalten, wenn sie gebraucht werden, 
also PWM ausschalten. Dann bleiben sie stehen und werden durchs die 
Getriebe-Übersetzung gehalten. Das sollte man sowieso machen, da ein 
Servo, der immer gegen einen Anschlag drückt warm wird. Deswegen ist bei 
mir mal ein Servo richtig abgebrannt. Durch die Erwärmung verstellt sich 
bei einfachen Typen der Winkel und das kann das Problem verschlimmern.

von Stefan F. (Gast)


Lesenswert?

Verteile das auf mehrere Mikrocontroller. Ohne großartige Klimmzüge sind 
10 Servos an einem ATtiny möglich. Nimm vier davon und verbinde sie per 
I2C oder irgend einer anderen seriellen Schnittstelle mit deinem ATmega.

Das Auslagern des zeitkritischen Teils auf separate Controller 
verinfacht auch die Programmierung ganz erheblich.

Zum abgucken: http://stefanfrings.de/servocontroller/index.html

von Stefan F. (Gast)


Lesenswert?

> 8-Bit Auflösung für die Servo-Pulsbreite ist nicht so der Bringer

Das dachte ich auch mal. Aber in der Praxis wirst du zwischen 16bit und 
8bit keinen Unterschied bemerken. So genau arbeiten die Dinger ohnehin 
nicht.

von Stefan F. (Gast)


Lesenswert?

> Du bräuchtest also 3 Arduino Nanos über eine Schnittstelle verbunden.
> Was spricht gegen Multiprozessing?

Nichts.

> So einen Schwachsinn können sich auch nur "Arduidioten" ausdenken....

Das halte ich ganz und gar nicht für Schwachsinn. Mit Welcher Begründung 
kommst du zu dieser krassen Bemerkung?

> Zwei PCA9685 kosten ca. 30 Euro
> Wie kommst du da drauf? ... (Vorschlag für 2x 5,99)

Arduino Nanos sind immer noch bedeutend billiger, falls es noch keiner 
gemerkt hat. Und die von mir vorgeschlagenen ATtinies kosten bei 
Reichelt noch weniger, und man muss nicht 6 Wochen auf die Lieferung 
warten oder gar zum Zoll fahren.

von Harry L. (mysth)


Lesenswert?

Tja, wenn man nicht programmieren kann, nimmt man eben für jede popelige 
Funktion einen eigenen µC - typisch Arduino-Jünger

Dabei vergessen sie meist, daß das Kommunikationsprotokoll zwischen den 
µCs für diese Anfänger i.d.R. die viel grössere Hürde darstellt.

Man muß auch keine 6 Wo. auf den PCA9685 warten.
Mein Link zeigt auf einen deutschen Händler, und da hat man die Teile 
i.d.R. innerhalb von 2-3 Tagen.

von Lukas D. (programmierer12)


Lesenswert?

Stefan U. schrieb:
> Verteile das auf mehrere Mikrocontroller. Ohne großartige Klimmzüge sind
> 10 Servos an einem ATtiny möglich. Nimm vier davon und verbinde sie per
> I2C oder irgend einer anderen seriellen Schnittstelle mit deinem ATmega.
>
> Das Auslagern des zeitkritischen Teils auf separate Controller
> verinfacht auch die Programmierung ganz erheblich.
>
> Zum abgucken: http://stefanfrings.de/servocontroller/index.html

Die Lösung klingt nach einem wirklich interessanten Ansatz...
Ich glaube das werde ich mal probieren müssen ;)

von Stefan F. (Gast)


Lesenswert?

> Dabei vergessen sie meist, daß das Kommunikationsprotokoll zwischen
> den µCs für diese Anfänger i.d.R. die viel grössere Hürde darstellt.

Warum hast du (Harry L) dann den PCA9685 vorgeschlagen?

> Tja, wenn man nicht programmieren kann, nimmt man eben für jede
> popelige Funktion einen eigenen µC

Na und, Hauptsache, die Bastelei funktioniert an Ende.

Ich denke, es wird auch schwierig sein, eine 1-Chip Lösung in Handarbeit 
zu verarbeiten. Da werden ziemlich viele Leitungen sternförmig zum µC 
zusammen laufen. Eine dezentrale Lösung mit I2C Bus und kleineren IC's 
lässt sich viel leichter handhaben.

von Harry L. (mysth)


Lesenswert?

Stefan U. schrieb:
>> Dabei vergessen sie meist, daß das Kommunikationsprotokoll zwischen
>> den µCs für diese Anfänger i.d.R. die viel grössere Hürde darstellt.
>
> Warum hast du (Harry L) dann den PCA9685 vorgeschlagen?
>
>> Tja, wenn man nicht programmieren kann, nimmt man eben für jede
>> popelige Funktion einen eigenen µC
>
> Na und, Hauptsache, die Bastelei funktioniert an Ende.
>
> Ich denke, es wird auch schwierig sein, eine 1-Chip Lösung in Handarbeit
> zu verarbeiten. Da werden ziemlich viele Leitungen sternförmig zum µC
> zusammen laufen. Eine dezentrale Lösung mit I2C Bus und kleineren IC's
> lässt sich viel leichter handhaben.

Merkst du gar nicht, wie du dir widersprichst?
Oder kennst du einfach den PCA9685 nicht?

Aber Hauptsache man gibt seinen Senf dazu....

von Stefan F. (Gast)


Lesenswert?

Der PCA9685 wird über eine I2C Schnittstelle angesteuert.

Du hast argumentiert, "daß das Kommunikationsprotokoll zwischen den
µCs für diese Anfänger i.d.R. die viel grössere Hürde darstellt."

Dann sollte man "diesem Anfänger" doch wohl eher nicht diesen Chip 
empfehlen, oder?

Ich würde ihm allerdings schon dazu raten, sich mit dem I2C Protokoll zu 
beschäftigen, denn ich finde den von Dir vorgeschlagenen Chip für diesen 
Fall sehr gut. Ich habe ja auch nicht von I2C abgeraten.

von AntiMaker (Gast)


Lesenswert?

Stefan U. schrieb:
> Dann sollte man "diesem Anfänger" doch wohl eher nicht diesen Chip
> empfehlen, oder?

Warum? für den PCA gibt's das Kommunikationsprotokoll über I2C fix und 
fertig implementiert als Arduino-Bibliothek. Ziemlich Deppen- und 
Maker-Sicher.

https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library


Bei einer eigenen Multi-µC-Lösung muss er selber ein Protokoll entwerfen 
und implementieren.

von Stefan F. (Gast)


Lesenswert?

> für den PCA gibt's das Kommunikationsprotokoll über I2C fix und
> fertig implementiert als Arduino-Bibliothek.

> Bei einer eigenen Multi-µC-Lösung muss er selber ein Protokoll
> entwerfen und implementieren.

Ich stimme Dir zu.

von Markus (Gast)


Lesenswert?

>Bei einer eigenen Multi-µC-Lösung muss er selber ein Protokoll entwerfen
>und implementieren.

Wahrscheinlich ein kaum zu lösende Aufgabe,
1
#include <Servo.h>
2
3
#define PIN_SERVO0 8
4
#define PIN_SERVO1 9
5
#define PIN_SERVO2 10
6
7
Servo servo0;
8
Servo servo1;
9
Servo servo2;
10
11
void setup()
12
{
13
  servo0.attach(PIN_SERVO0);
14
  servo1.attach(PIN_SERVO1);
15
  servo2.attach(PIN_SERVO2);
16
    
17
  Serial.begin(115200);
18
  while (!Serial) {
19
    ; // wait for serial port to connect. Needed for native USB port only
20
  }
21
}
22
23
uint8_t getChar()
24
{
25
  while (Serial.available() == 0);
26
  return Serial.read();
27
}
28
29
void loop()
30
{
31
  uint8_t c = 0;
32
  uint8_t servoNumber;
33
  uint8_t servoVal;
34
35
  do
36
  {
37
    c = getChar();
38
  } while (c != 's');
39
  
40
  servoNumber = getChar();
41
  servoVal    = getChar();
42
43
  if(servoNumber==0) servo0.write(servoVal);
44
  if(servoNumber==1) servo1.write(servoVal);
45
  if(servoNumber==2) servo2.write(servoVal);
46
47
48
}

von Stefan F. (Gast)


Lesenswert?

Ähnlich simpel ist auch meine Lösung mit dem ATtiny, die wire Library 
von Arduino macht es einem leicht:
1
Wire.beginTransmission(0x1E); // adresse
2
Wire.write(94); // erster Servo in die Mitte
3
Wire.write(94); // zweiter Servo in die Mitte
4
Wire.write(125); // dritter Servo nach rechts
5
Wire.write(62); // vierter Servo nach links
6
Wire.endTransmission();

von Markus (Gast)


Lesenswert?

OK, kann man auch machen. Je nachdem, welche Schnittstelle man 
bevorzugt.
Bei der seriellen wäre es eine Eindrahtschnittstelle: TX

Interessant wäre vielleicht auch die Verwendung eines BluePills:
http://wiki.stm32duino.com/index.php?title=Blue_Pill

Der hat mehr Pins, damit könnte man vielleicht auch 16 Servos betreiben, 
wenn das mit 3.3V geht.

von Stefan F. (Gast)


Lesenswert?

> wenn das mit 3.3V geht.

Hat bei mir bisher immer geklappt.

von Stefan F. (Gast)


Lesenswert?

Eine Korrektur:
1
Wire.beginTransmission(0x0F); // 7bit Adresse
2
Wire.write(94); // erster Servo in die Mitte
3
Wire.write(94); // zweiter Servo in die Mitte
4
Wire.write(125); // dritter Servo nach rechts
5
Wire.write(62); // vierter Servo nach links
6
Wire.endTransmission();

Ich habe den Schaltplan schön gezeichnet:
http://stefanfrings.de/servocontroller/schematics.png

Die Firmware kannst du als hex File runterladen.
http://stefanfrings.de/servocontroller/ServoController.zip

Du wirst noch einen ISP Programmieradapter brauchen. Zur Not eignet sich 
dazu ein Arduino mit dem ISP Sketch.

Ich würde die Variante mit ATtiny2313 bevorzugen, da dieser mehr Pins 
zur Adress-Codierung bereit stellt.

von Frank K. (fchk)


Lesenswert?

Stefan U. schrieb:

>> Zwei PCA9685 kosten ca. 30 Euro
>> Wie kommst du da drauf? ... (Vorschlag für 2x 5,99)
>
> Arduino Nanos sind immer noch bedeutend billiger,

Also bei Digikey kosten PCA9685PW 2.03€ aktuell. Und wer keine PCB 
machen will, findet unter 1528-1068-ND ein Dreierpack TSSOP28->DIL28 
Breakout-Boards für 4.34€.

Und alles lieferbar.

fchk

von Stefan F. (Gast)


Lesenswert?

Ich finde ziemlich krass, wie unterschiedlich die Verkaufpreise dieser 
Chips sind.

Wenn man die bisherigen Vorschläge so anschaut, scheint I2C schonmal 
fest zu stehen.

von Horst S. (h3aau)


Lesenswert?

// hier mal das ganze über den Timer. es können alle Pins verwendet 
werden.
String cmd="";
String sservo="";
char fbuffer[100];
unsigned int xxx=123;
unsigned int yyy=00;

#define IndexMax 6                          // Anzahl der servos
#define ServoMIN 500                       // Mittelwert des Servos in 
usec
#define ServoMAX 2500                       // Mittelwert des Servos in 
usec
#define ServoHome 1500                      // Mittelwert des Servos in 
usec
#define INTERVAL 20000                      // 20ms
//int S[IndexMax]={A3,A2,A1,A0,A4,A5};          // Pins für die Servos;
int S[IndexMax]={A3,A2};          // Pins für die Servos;
volatile int W[IndexMax];                            // Impulswerte der 
Servos in usec
volatile int  Index=0;                      // Zeiger auf Servo/Daten
volatile int  Index1=0;                     // Zeiger auf Servo/Daten

void Servo_init(void)
{
  int i;
  for (i=0;i<IndexMax;i++)
    {
    pinMode(S[i], OUTPUT);    // Pins als Ausgang definieren
    W[i]=ServoHome;           // vorbelegung der Servos
    sprintf(fbuffer, "Pin %i ist Servo %i",S[i],i);
    Serial.println(fbuffer);
    }

// Timer 1
  noInterrupts();           // Alle Interrupts temporär abschalten
  TCCR1A = 0;               // Register löschen
  TCCR1B = 0;               // Register löschen
  TCNT1 = 100000;           // Timer vorbelegen, beliebig
  TCCR1B |= (1 << CS11);    // 8 als Prescale-Wert = 500nsec Takt
  TIMSK1 |= (1 << TOIE1);   // Timer Overflow Interrupt aktivieren
  interrupts();             // alle Interrupts scharf schalten
}

ISR(TIMER1_OVF_vect)               // Interrupt Timer/Counter1 OVERFLOW
{
int i,T1wert;
  digitalWrite(S[Index1],LOW);     // aktuellen Servo abschalten
  if (Index<IndexMax)
     {
     digitalWrite(S[Index],HIGH);  // neuen Servo anschalten
     T1wert=65535-(W[Index]*2);    // anzahl der Takte berechnen
     Index1=Index;
     Index++;
     }
  else
     {
     Index=0;
     T1wert=65535-(INTERVAL*2);
     for (i=0;i<IndexMax;i++) T1wert+=(W[i]*2);
     }
  TCNT1H = (uint8_t) (T1wert >>8 );  // Timer mit neuer Impulszeit 
starten
  TCNT1L = (uint8_t) (T1wert     );
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println("Starting...");
  Servo_init();
}


void loop() {

int i;

  if (Serial.available() > 0)
  {
    cmd = Serial.readStringUntil(10);
    Serial.println(cmd);




    //Serial.print("Moving Servo to: ");
    //Serial.println(cmd);

    //2-120
    sservo = cmd.substring(0,1);
    cmd = cmd.substring(2);
    yyy=sservo.toInt();
    xxx=cmd.toInt();

    if ((xxx >= ServoMIN) && (xxx <= ServoMAX) && (yyy < IndexMax))
      {
      sprintf(fbuffer, "Moving servo %2d to %3d test",yyy, xxx);
      Serial.println(fbuffer);
      W[yyy]=xxx;
      }
    else
      {
      Serial.println("Value out of range");
     }
  }
}

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

> hier mal das ganze über den Timer

Toll, noch eine Variante davon. Und so Zeitnah. Wie steuerst du damit 32 
Servos?

Mein vor 3 Monaten genannter Vorschlag konnte schon 10 Servos ansteuern 
und lässt sich immer noch ganz leicht auf 20 erweitern.

Wir waren aber schon längst bei der Erkenntnis, dass dieser PCA9685 die 
bessere Wahl ist.

von m.n. (Gast)


Lesenswert?

Horst S. schrieb:
> TCNT1 = 100000;           // Timer vorbelegen, beliebig

Das merkt man ;-)

von Peter D. (peda)


Lesenswert?

Jobst M. schrieb:
> Der 4017 ist der richtige Baustein.

Nö.
Der kann nur 9 Servos ansteuern und läßt sich nicht kaskadieren.

Besser nimmt man daher 4 Stück 74HC164 kaskadiert. Die brauchen 
insgesamt 2 Outputs des MCs, wovon der Takt ein Compare-Output ist, 
damit jitterfrei.
Der Timerinterrupt lädt dann den nächsten Servowert aus nem 32Byte-Array 
nach und schiebt bei jedem ersten Wert das 1Bit raus.

von Horst S. (h3aau)


Lesenswert?

nimm einfach einen atmega2560, der hat genug freie pins.

von Retro N. (retronerd)


Lesenswert?

Mit einem ATMega328 kannst Du keine 32 Servos direkt ansteuern, 8 via 
Multiplexing aber schon:
https://www.mikrocontroller.net/articles/Modellbauservo_Ansteuerung#Signalerzeugung_f.C3.BCr_mehrere_Servos_mittels_Timer_.28C.29

Das kannst Du dann mit einem 24 Channel Breakout-Board

https://eckstein-shop.de/Adafruit-24-Channel-12-bit-PWM-LED-Driver-SPI-Interface?curr=EUR&gclid=EAIaIQobChMIpd74g9WY1wIVyqgYCh0UQQCzEAQYAiABEgIm5_D_BwE

kombinieren, denn der 328 hat bei der Ansteuerung per SPI sowieso nix zu 
tun. Zusammen mit einem Arduino Nano Clone liegst Du dann bei unter 20 
EUR.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

> Mit einem ATMega328 kannst Du keine 32 Servos direkt ansteuern,
> 8 via Multiplexing aber schon

8 ist aber wenig. Mein Code steuert mittels Multiplexing 10 Servos mit 
einem Timer an. Der ATMega328 hat 3 Timer, was demnach für 30 Servos 
reicht. So viele I/O Pins hat der Chip aber gar nicht.

http://stefanfrings.de/servocontroller/index.html

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.