Digital IO erweitern - mit PWM für Servoansteuerung

Hallo zusammen!

ich bin neu in der Arduino Welt und schon fleissig am rumexperimentieren.
Bis jetzt habe ich schon einige Einsteigertutorials durch.

Ich habe nun zuletzt mein eigenes Shield fertiggebaut, welches mir ermöglich ein GLCD anzuschliessen. Ausserdem hat es noch einen Multiplexer für weitere Analogeingänge mit an Board.

Da ich aber nur das Arduino UNO besitze gehen mir jetzt die Digital IOs aus.
Es sind nur noch 2 übrig. Ein normaler IO und ein IO mit PWM.

Mein nächstes Projekt wird mit Servomotoren sein. Leider habe ich im Moment nur die Möglichkeit 1 Servo an den letzen PWM anzschliessen, wenn ich auch das GLCD und mein Muxer verwenden möchte.

MEINE FRAGE:

Gibt es eine Möglichkeit über Schieberegister meine IOs zu Erweitern, das ich mehrere Servos über PWM ansteuern kann? Sowas für ShiftPWM für Leds, halt nur für Servos?

Zur not könnte ich noch 1-2 IOs frei machen um das Schieberegister zu betreiben.

mfg
moe

  1. die Bibiothek servo steuert 12 Servos an jedem x-beliebigen PIN
  2. Die analogen Eingänge können als digitale Ein/Ausgänge verwendet werden.
    Grüße Uwe

hallo uwefed,

hey super, dass wusste ich nicht, das die Servo Bibliothek auch die nicht PWM gekennzeichneten IOs verwenden kann.
Leider sind die Analogeingänge auf dem Board schon alle belegt (5x GLCD, 1x Mux).

Die Mux IOs kann ich wohl nicht für meinen GLCD verwenden, oder sogar zur Servoansteuerung?
Einlesen kann ich ja Spannungen, aber es soll wohl auch in die andere Richtung funktionieren. Kennt sich damit jemand aus?

vielen Dank für die Hilfe
Gruß
moe

EDIT:

lässt dieser i2C Expander PWM Steuerung zu?
http://www.watterott.com/de/Breakout-Board-for-PCF8575-I2C-Expander

dieser Expander hier brauch wohl zu viele IOs vom Arduino Board, welche mir ja fehlen...
http://www.watterott.com/de/TLC5940-Breakout?xaf26a=egvkr861fnp1bk1090dh3gdvp6

Breakout Board for PCF8575 I2C Expander

Servos brauchen kein PWM Signal sondern ein PPM Signal: einen Spannungsimpuls von 1mS bis 2mS Dauer ( entspricht 0 bis 180 Grad) der mit 50Hz wiedeholt wird.

moe69:
Die Mux IOs kann ich wohl nicht für meinen GLCD verwenden, oder sogar zur Servoansteuerung?
Einlesen kann ich ja Spannungen, aber es soll wohl auch in die andere Richtung funktionieren. Kennt sich damit jemand aus?

Mux schalten immer einen "Eingang" zu einen der "Ausgänge" AnalogMUX wie der CD4067 funktionieren dabei für analogspannungen in beide Richtungen. E zu A und A zu E.
Für GLCD-Ansteuerung empfielt sich ein I2C Expander oder ein Shieberegister Typ 74HC595.

moe69:
lässt dieser i2C Expander PWM Steuerung zu?
http://www.watterott.com/de/Breakout-Board-for-PCF8575-I2C-Expander

Nein, nur mit zuviel programmier-Aufwand.

moe69:
dieser Expander hier brauch wohl zu viele IOs vom Arduino Board, welche mir ja fehlen...
http://www.watterott.com/de/TLC5940-Breakout?xaf26a=egvkr861fnp1bk1090dh3gdvp6

Der TLC5940 ist ein LED PWM Treiber mit Konstantstromsenken. Der Strom fließt vom Ausgang richtung Masse oder anders gesagt von + über die LED in den Ausgang, entsprechend einem Open Collektor Ausgang mit Stromlimitierungsfunktion. Andere Anwendungen als LED anzusteuern sind schwierig bis unmöglich.

Viele Grüße Uwe

moe69:
Die Mux IOs kann ich wohl nicht für meinen GLCD verwenden, oder sogar zur Servoansteuerung?
Einlesen kann ich ja Spannungen, aber es soll wohl auch in die andere Richtung funktionieren. Kennt sich damit jemand aus?

Mux schalten immer einen "Eingang" zu einen der "Ausgänge" AnalogMUX wie der CD4067 funktionieren dabei für analogspannungen in beide Richtungen. E zu A und A zu E.
Für GLCD-Ansteuerung empfielt sich ein I2C Expander oder ein Shieberegister Typ 74HC595.

Hallo Uwe,

also das bedeutet, entweder ich hole mir einen I2C Expander um mein GLCD darüber anzusteuern um wieder freie Digitale Ports zu bekommen
oder halt ein Schieberegister. Dieses Schieberegister besitze ich sogar, nur wie ich dieses mit dem GLCD zum laufen bekomme kann ich mir im Moment noch nicht vorstellen. Habe bis jetzt damit nur mit LEDs gearbeitet.

Könnte ich also mein Muxer CD4067 auch zum ansteuern von Servos verwenden? Praktisch seine Analogeingänge als Ausgänge umgestalten?

mfg
moe

moe69:
also das bedeutet, entweder ich hole mir einen I2C Expander um mein GLCD darüber anzusteuern um wieder freie Digitale Ports zu bekommen
oder halt ein Schieberegister. Dieses Schieberegister besitze ich sogar, nur wie ich dieses mit dem GLCD zum laufen bekomme kann ich mir im Moment noch nicht vorstellen. Habe bis jetzt damit nur mit LEDs gearbeitet.

Du kannst die 8 Datenleitungen über das Schieberegister oder I2Cexpander ausgeben; dazu mußt Du aber die Bibiothek umschreiben.

moe69:
Könnte ich also mein Muxer CD4067 auch zum ansteuern von Servos verwenden? Praktisch seine Analogeingänge als Ausgänge umgestalten?
mfg moe

Nein; Du kannst die Steuereingänge des Servo nicht in der Luft ohne Steuersignal lassen. sie bleiben sicher nicht in der letzten Postion stehen.
Zum ansteuern des CD4067 brauchst Du 4 digital Ausgänge.

Grüße Uwe

Hallo Uwe, danke Dir für die Hilfe.

Also, ich glaube das mit dem Schieberegister oder dem I2C Expander wird etwas aufwändiger nehme ich an?

Was ich mir jetzt noch überlegt habe ist, dass ich die 5 Analogeingänge die mein GLCD verbraucht ja auf den Mux legen könnte.
So hätte ich 5 weitere Ausgänge ja frei, da die Analog-INs ja auch als Ausgang zu setzen sind.

Momentan ist meine Belegung wie Belegung1

Wenn ich die Analogpins des GLCD auf den Muxer lege, dann wäre es wie Belegung2

Kanal - Belegung1 - Belegung2

A0 = MUX MUX
A1 = GLCD - frei -
A2 = GLCD - frei -
A3 = GLCD - frei -
A4 = GLCD - frei -
A5 = GLCD - frei -

0 = MUX MUX
1 = MUX MUX
2 = - frei - -frei-
3 = - frei - -frei-
4 = GLCD GLCD
5 = GLCD ...
6 = GLCD
7 = GLCD
8 = GLCD
10= GLCD
11= GLCD
12= MUX
13= MUX

MUX1 = - frei - GLCD
MUX2 = - frei - GLCD
MUX3 = - frei - GLCD
MUX4 = - frei - GLCD
MUX5 = - frei - GLCD
MUX6 = - frei - -frei-
MUX7 = - frei - -frei-
MUX8 = - frei - -frei-
.....

Die Frage ist jetzt nur, wie sag ich der GLCD Library, das ich die Analog-Pins auf den Muxer lege.
In der Config sieht das ja so aus:

//
/
Configuration for assigning LCD bits to Arduino Pins /
/
/
/* Data pin definitions
*/
#define glcdData0Pin 8
#define glcdData1Pin 9
#define glcdData2Pin 10
#define glcdData3Pin 11
#define glcdData4Pin 4
#define glcdData5Pin 5
#define glcdData6Pin 6
#define glcdData7Pin 7

/* Arduino pins used for Commands

  • default assignment uses the first five analog pins
    */

#define glcdCSEL1 14
#define glcdCSEL2 15

#if NBR_CHIP_SELECT_PINS > 2
#define glcdCSEL3 3 // third chip select if needed
#endif

#if NBR_CHIP_SELECT_PINS > 3
#define glcdCSEL4 2 // fourth chip select if needed
#endif

#define glcdRW 16
#define glcdDI 17
#define glcdEN 18
// Reset Bit - uncomment the next line if reset is connected to an output pin
//#define glcdRES 19 // Reset Bit

#endif //GLCD_PIN_CONFIG_H

Die Pins wären somit 14, 15, 16, 17, 18... diese müsste ich mit dem Muxer verknüpfen.
Analoge Spannungen lese ich mit dem Muxer über folgendes Skript ein:

/* Ultra-Shield-BASIC2
*/

int s0 = 0; // MUX-Kontroll-Pin s0 RX
int s1 = 1; // MUX-Kontroll-Pin s1 TX
int s2 = 12; // MUX-Kontroll-Pin s2
int s3 = 13; // MUX-Kontroll-Pin s3
int SIG_pin = 5; //MUX-Eingangs-Pin

#include <glcd.h>
#include <fonts/allFonts.h>

//---------------------------------------------------------------------------------

void setup()
{

pinMode(s0, OUTPUT); // Pin 2 digital als Ausgang
pinMode(s1, OUTPUT); // Pin 3 digital als Ausgang
pinMode(s2, OUTPUT); // Pin 12 digital als Ausgang
pinMode(s3, OUTPUT); // Pin 13 digital als Ausgang

// alle Kontroll-Pins auf 0 = Kanal 0
digitalWrite(s0, LOW);
digitalWrite(s1, LOW);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);

GLCD.Init();
GLCD.SelectFont(System5x7);

}

//-----------------------------------------------------------------------------------

void loop()
{

int LeseMux(0) // lies Kanal Nr. 0 am Muxer

}

//-----------------------------------------------------------------------------------------

// Funktion LeseMux

int LeseMux(int kanal)
{
int kontrollPin[] = {s0, s1, s2, s3}; // Array fuer Kontroll-Pins

int muxKanal[16][4]= // Array fuer Kanaele
{
{0,0,0,0}, //Kanal 0
{1,0,0,0}, //Kanal 1
{0,1,0,0}, //Kanal 2
{1,1,0,0}, //Kanal 3
{0,0,1,0}, //Kanal 4
{1,0,1,0}, //Kanal 5
{0,1,1,0}, //Kanal 6
{1,1,1,0}, //Kanal 7
{0,0,0,1}, //Kanal 8
{1,0,0,1}, //Kanal 9
{0,1,0,1}, //Kanal 10
{1,1,0,1}, //Kanal 11
{0,0,1,1}, //Kanal 12
{1,0,1,1}, //Kanal 13
{0,1,1,1}, //Kanal 14
{1,1,1,1} //Kanal 15
};

// durchlaufe die 4 s
for(int zaehler = 0; zaehler < 4; zaehler ++)
{
digitalWrite(kontrollPin[zaehler], muxKanal[kanal][zaehler]);
}

int wert = analogRead(SIG_pin); // lese Wert SIG-Pin
//return the value
return wert;
}

Wer kann mir nun dabei helfen?

mfg
moe