Für eine Servosteuerung mit einem Nano verwende ich 16 Tasten an den
analogen Inputs A0 - A7. Nun möchte ich über I2C mit einem PCF8574 die
Portanzahl vergrößern, um zusätzlich 8 monostabile Relais anzusteuern.
Für I2C brauche ich die Pins A4 und A5.
Ist es ein gängiger Ansatz, zwischen analogem Input und I2C-Verwendung
dieser Pins im Sketch (in der Loop) hin und her zu schalten?
Die meiste Zeit ist der Arduino in einer Schleife damit beschäftigt,
Tastendrücke zu erkennen, dann bewegt er die entsprechenden Servos und
schaltet kurzzeitig auf I2C um, um Relais über den Port Expander zu
schalten. Danach gehtˋs wieder als analoger Input weiter.
Martin schrieb:> Ist es ein gängiger Ansatz, zwischen analogem Input und I2C-Verwendung> dieser Pins im Sketch (in der Loop) hin und her zu schalten?
Nö. Wenn du sowieso schon einen Portexpander benutzen willst, kannst du
doch auch gleich einen zweiten verwenden, um deine Tasten einzulesen.
Martin schrieb:> Für eine Servosteuerung mit einem Nano verwende ich 16 Tasten an> den> analogen Inputs A0 - A7. Nun möchte ich über I2C mit einem PCF8574 die> Portanzahl vergrößern, um zusätzlich 8 monostabile Relais anzusteuern.> Für I2C brauche ich die Pins A4 und A5.>> Ist es ein gängiger Ansatz, zwischen analogem Input und I2C-Verwendung> dieser Pins im Sketch (in der Loop) hin und her zu schalten?>> Die meiste Zeit ist der Arduino in einer Schleife damit beschäftigt,> Tastendrücke zu erkennen, dann bewegt er die entsprechenden Servos und> schaltet kurzzeitig auf I2C um, um Relais über den Port Expander zu> schalten. Danach gehtˋs wieder als analoger Input weiter.
Wenn du die selben Pins belegst, sind die Probleme Vorprogrammiert....
Also warum verwendest du nicht eine I²C Switchmatrix oder alternativ ein
I²C A/D-Converter?
Oder einfach ein etwas größerer µC?
Gibt es ein Grund bei dem µC zu bleiben?
Es gibt µC's mit 8 Pin und I²C.
es gibt aber auch µCs mit gaaaanz vielen Pins.
Das Ganze ist historisch gewachsen. Es ist mir schon klar, dass es
Mikrocontroller mit mehr Beinchen gibt 🤓. Aber ich hänge an meinem Nano
;-)
Plan B wäre bei 2 Servos auf Tasten zu verzichten und nur I2C zu
verwenden. Die Servos können mit dem Sketch/Hardware auch über DCC
(Protokoll zu Steuerung von Modellbahnen) angesteuert werden.
Martin schrieb:> historisch gewachsen.
Gutes Argument :-)
Dennoch, warum verwendest du nicht eine I²C Schaltmatrix, oder eben für
die Tasten ein weiteren PCF8574?
Die lassen sich ja mit 3 Adresspins gut adressieren und wenn der
Adressraum nicht ausreicht gibt es noch den PCF8574A ?
Anbei mal der Schaltplan. 2 Taster pro analog-Input, einmal 10k und
einmal 47k Widerstand, 10k als Pullup. SDA und SCL habe ich für eine
Erweiterungsplatine rausgeführt (links unten).
Die Servo-Platine ist bereits aus China unterwegs. Mir ging es nur um
die optionale Erweiterung durch eine zusätzliche Relais-Platine, weil
ich I2C ausprobieren wollte.
Die Taster sollen an der Hauptplatine angeschlossen sein. Es ginge
natürlich auch an der Erweiterungsplatine. Habe auch einen MCP23017 hier
rumliegen.
Das Hin- und Herschalten von Funktionen an PINs kenne ich von PICs. Die
können ja auch abwechselnd auf In- und Output im Code eingestellt
werden.
Kanst du ev einer der S1~S8 als SCL verwenden?
Hab das schon mal bei einem 8Pin µC gemacht und den SDA mit der
Servofrequenz synchronisiert. Auch RX wäre zur Not dafür verwendbar ;-)
Ich habe das jetzt ´mal mit einem Uno prototypisch getestet.
Wenn ich nach den Write-Befehlen auf den Port Expander ("Extension") ein
"Wire.end ()" einbaue, dann scheint es zu funktionieren.
Es werden sowohl die analogen Inputs abgefragt als auch die Relais
geschaltet.
Martin schrieb:> Gibt´s den Wire.end Befehl überhaupt offiziell?
Naja...
Erstens ist es kein Befehl, ich glaube C++ kennt gar keine Befehle, es
ist eine Methode.
Das eigentliche Problem ist die Doppelverwendung.
Wenn man mit den I2C Pins wackelt, kann/wird der Slave das als
Daten/Takt interpretieren und aus dem Tritt kommen.
Bei SPI kann man das wagen, wenn man CS high hält, aber bei I2C wird das
nix.
Ja, das wäre auch eine Möglichkeit. Hatte ich hier schon ´mal
thematisiert: Beitrag "Analog Inputs liefern unterschiedliche Werte bei verschiedenen Arduino Nanos"
Beim aktuellen Layout, war ich immerhin so un-geizig und habe externe
PUs an den Analog-Eingängen spendiert.
Bin aber immer noch zu geizig bzgl. der Anzahl der zu verlegenen
Leitungen ... (wenn nicht an GND).
Martin schrieb:> Ist es ein gängiger Ansatz, zwischen analogem Input und I2C-Verwendung> dieser Pins im Sketch (in der Loop) hin und her zu schalten?
Nein. Guck dir mal für die auf dem I²C-Bus sitzenden Komponenten die
zulässigen Signalpegel an (Unter Recommended Operating Conditions die
Parameter V_IL und V_IH). Beim PCF8574 ist bspw. der Bereich 0.3 ...
0.7*VCC nicht zulässig. Du wirst nicht garantieren können, dass sich die
Analogsignale in dem Bereich bewegen, oder?
Wolfgang schrieb:> Nein. Guck dir mal für die auf dem I²C-Bus sitzenden Komponenten die> zulässigen Signalpegel an (Unter Recommended Operating Conditions die> Parameter V_IL und V_IH). Beim PCF8574 ist bspw. der Bereich 0.3 ...> 0.7*VCC nicht zulässig. Du wirst nicht garantieren können, dass sich die> Analogsignale in dem Bereich bewegen, oder?
Danke, das war ein guter Hinweis. Das bedeutet aber, wenn ich meine
Widerstände gegen GND an den Tastern so wähle, dass am Analog-Eingang
eine Spannung zwischen 1,5 und 3,5 V beim Drücken anliegt, es keine
Probleme mit dem PCF8574 geben sollte, da er diese Werte nicht
fehlinterpretiert, oder?
Empirisch mit ein paar Widerständen getestet:
- Bei 47k Pull-down --> keine Probleme (Wert am Nano-Eingang A4/A5 ca.
860, entspricht umgerechnet 4,3 V)
- Bei 4,7k hängt sich der Uno komplett auf
- Bei dem 10k --> I2C hängt, geht aber nach Loslassen der Taste weiter
(548)
- Bei 15k (645 / 3,15V) oder 22k (706 / 3,44 V) keine negativen
Auswirkungen
Habe auch mal mit Wire.end() getestet, macht aber keinen Unterschied.
Es wird dann aber das µC-Register TWCR (2 Wire control register) auf 0
gesetzt.
Man muss die analogen Inputs auch nicht immer wieder extra auf INPUT
setzen.
Werde das mit der endgültigen Platine weiter testen. Plan B ist ja wie
gesagt auf die Taster für 2 Servos zu verzichten. Oder das Ganze
komplett anders zu gestalten.
Danke für eure Hilfe!
Martin schrieb:> Probleme mit dem PCF8574 geben sollte, da er diese Werte nicht> fehlinterpretiert, oder?
Da würde ich nicht drauf Wetten....:-(
So ein PCF8574 kann sich derart "Hängen" das er nicht mehr reagiert,
wenn er nach einem Start-Condition seine Adresse sieht und dann
Datensalat.
Was passiert wenn er grad angesprochen wird und Gleichzeitig eine Taste
gedrückt wird?
Martin schrieb:> Das bedeutet aber, wenn ich meine Widerstände gegen GND an den Tastern> so wähle, dass am Analog-Eingang eine Spannung zwischen 1,5 und 3,5 V> beim Drücken anliegt, es keine Probleme mit dem PCF8574 geben sollte,> da er diese Werte nicht fehlinterpretiert, oder?
Vielleicht habe ich mich da etwas unglücklich ausgedrückt: Bei
5V-Betrieb ist der Bereich 1,5 bis 3,5 V beim PCF8574 der VERBOTENE
Bereich.
Und bedenke die Pull-Up Widerstände vom I²C-Bus
besserwisser schrieb:> nimm doch einen PCA9685 für die Servos, dann werden 6 pins frei und du> kannst 16 Sevos ansteuern.
Hey ja auf die Idee hätte ich auch kommen können ...GRMPF..LOL.. ich
denke das ist die Beste Lösung und spart den TO auch noch viel Coding
Aufwand ;-)
Ich verwende ja oft den VSC0055 für solche Anwendungen der hat außer PWM
noch andere Nützliche Dinger drin.
Aber Ja du hast recht der PCA9685 ist ideal dazu geeignet habe ich doch
auch schon verwendet :-)
Nur Frage kann der die Frequenz, die für Servos geeignet ist?
der ist ja eigentlich für LED's hab die Daten jetzt nicht mehr im Kopf.
Was würde ich machen?
Mir würde es ich nicht gefallen, mit zwei Tasten das komplette IIC
Protokoll "morsen" zu können.
Las doch die Tasten an den I2C Pins weg und leg die nun vier
freigewordenen Tasten mit zB. 1K mit auf die anderen Analogen Eingänge.
Sind dann eben 3Stufen pro Analog-Eingang und der Bus bleibt frei.
Es gibt auch GPIO-Expander mit 16 Bit. Und man könnte 2 mit
unterschiedlichen Adress-Dekodierungen nehmen.
Dann könnte man den ganzen digitalen Krams (Taster/ Relais) über diese
Extender machen.
Oder gleich einen größeren Arduino nehmen.
Das aktuelle Design ist in meinen Augen etwas 'krank'.
Stefan ⛄ F. schrieb:> Wenn das nicht so wäre, würde er wohl kaum als Servo-Controller> verkauft.
na ja, dort werden ja auch Accus in der Zigarettenpackung mit 100Ah und
mehr verkauft.. nicht so vertrauenswürdig LOL
Hoffen wir mal das der PCA9685 nicht zur Gewerkschaft geht und sich
wegen Missbrauch beschwert, da er ja eigentlich als LED Kontroller
Designt wurde LOL
Nee mal Spaß bei Seite gehe davon aus ja dass es geht :-)
Da ich viel mit NANOs & Co. anstelle geht es mir von Zeit zu Zeit
ähnlich. Für solche Erweiterungen verwende ich aber TIMER 0 oder 2 ISRs
die mit 8MHz ein Shift register wie HC164 oder auch HC595 ansteuern. Die
Tastensteuerung ist im Multiplexbetrieb und stützt sich auf Peter Ds
Konzept. Gleichzeitig steuere ich mit anderen SR-Pins Ausgänge an und
habe praktisch keine Pin Begrenzungen. SPI macht den 328er "groß".
Die SR-Updates brauchen 1uS pro SR und wirkt sich nicht störend auf die
Timer-ISR aus. Beim UV-Belichter habe ich 56 LEDs/Displays zum Ansteuern
und 11 Tasten zum Einlesen. Das geschieht alles im Hintergrund aus der
ISR. Jedenfalls funktioniert das alles schön im Hintergrund ohne daß
sich der andere Code um irgendetwas befassen muß und macht Real-Time
Multitasking sehr einfach möglich. HW wird dann einfach in
korrespondierenden Registern virtualisiert und man braucht sich um
nichts mehr kümmern. Updates sind dann ähnlich der von uC Peripherie.
Ausserdem sind SR spottbillig im Vergleich zu Port Expandern. Port
Expander und SPI Erweiterungen haben auch den großen Vorteil das
Bord-Layout zu vereinfachen weil man den Parallel IO gerade dort
plazieren kann wo es zweckmässig ist. Bei großen uC mit viel Pins hat
man dann sonst oft einen Kuddelmuddel an Verbindungen mit denen man sich
nur rumplagen muß.
Auch könnte man mit weiteren Parallel SR wie HC165/589 auch noch jede
Menge Inputs einlesen. Das geht wesentlich schneller als I2C und ist mit
SPI Betrieb gleichzeitig möglich. Eine 1ms Zykluszeit des Timers ist da
vollkommen ausreichend um HW 1000 mal/s bedienen zu können. Das ist für
viele Real-World Interaktion vollkommen ausreichend.
Mit I2C steuere ich auch oft noch ein LCD Modul (PCF8574).
Mit I2C-SoftMaster kann man X-beliebige Pins verwenden. So gesehen hat
man auch mit dem NANO kaum Pin-Begrenzungen und kann sich die Special
Funktionalität der PINs leichter reservieren. Ich bin der Meinung, daß
man sich die Multifunktion-Pins erhalten sollte und einfachen digitalen
IO über SR erledigen sollte. Bitte beachten, daß die I2C-SoftMaster
Bibliothek(P.Fleury) ab IDE Version 1.8.10 nicht mehr richtig
funktioniert.
Die PCF8574s und PCA95xx Port Expander sind alle sehr bequem und
nützlich, SPI ist aber wesentlich schneller und unkomplizierter weil
kein Multi-Byte I2C-Protokoll bei 100-400kHz notwendig ist und man nur
die neuen Daten ins SPI-Datenregister eingeben muß bzw. Auszulesen. SR
haben auch den Vorteil 8-Bit breit zu sein und das macht bei
zusammengehörenden Pins auch die FW einfacher. Bei 16MHz Takt braucht
ein SPI Sendevorgang nur 1us. Mach das mal mit I2C. I2C hat eigentlich
mehr Sinn für wenig aktiven Datenverkehr. Für schnelle Sachen ist SPI
günstiger. Auch ist SPI bei sachgemässem Einsatz wesentlich
störunanfälliger und BUS-Störungen wie bei I2C gibt es nicht. Man sollte
I2C trotz seiner prinzipiellen Nützlichkeit nicht überbewerten und als
einzig seligmachende Option ansehen.
Man kann übrigens den von Arduino belegten TIMER0 ISR für eigehe Zwecke
ausnützen indem man zusätzlich einen T0 CTC Interrupt installiert. Dann
gibt es regelmässigen Zugang zur Arduino 1ms T0 Zeitbasis. Für kurze ISR
ist der neue CTC Interrupt auch kein Problem. Viel Code darf man da
allerdings nicht reinstecken. Sonst nehme ich für eigenes Timing den T2
CTC Betrieb nach eigenen Ermessen.
Man könnte auch Analog Pins für Tasteneingabe verwenden. Das erspart
natürlich auch Pins. Nur finde ich Peters Methode besser weil der schon
kurze und lange Tastendrücke auswerten kann und extrem zuverlässig
funktioniert.
Es gibt übrigens bei NXP I2C Port-Expander mit bis zu 40 IO Funktionen
als 5 Byte-Ports organisiert. (PCA9698)
Sind nur meine bisherigen Erfahrungen. Jeder sieht das natürlich anders
und man braucht sich nicht darüber zu streiten. Ich komme jedenfalls mit
solchen Strategien sehr gut zurecht.
Ein kleiner Zwischenbericht: die „kranke“ Doppelnutzung von A4/A5 als
I2C und analoge Inputs hat wie erwartet nicht sauber funktioniert.
Aktuell teste ich eine Lösung, bei der 4 Taster pro analogem Input
ausgewertet werden, ähnlich diesem Ansatz hier:
http://www.avr-asm-tutorial.net/avr_de/apps/tasten_schalter_adc/schalter/klavier.html
2 Taster gleichzeitig zu erkennen, ist bei mir eine Rahmenbedingung.
Das zugehörige Programm ist sehr hilfreich zur Bestimmung der
Widerstände. Da die China-Platinen recht günstig sind, hält sich der
finanzielle Verlust in Grenzen 😊
Das I2C funktioniert ansonsten „as designed“, ist bei mir
zeitunkritisch. Ansonsten würde ich eher mit 74HC595 SR oder 165er
arbeiten.
Again what learned!
Martin schrieb:> 2 Taster gleichzeitig zu erkennen, ist bei mir eine Rahmenbedingung.
Das geht aber auch als 4*4 Matrix an einem PCF8574/A. Dann kannst Du
sogar über den Interruptpin erkennen, ob überhaupt eine Taste gedrückt
ist und mußt nicht ständig den I2C-Bus abfragen.
Erst für >2 Tasten gleichzeitig braucht man noch eine Diode je Taster.
Es hätte problemlos gehen sollen. Was war das Problem? Ein Tastedruck
solllte das I2c nicht stören können (bei passenden Widerständen). Und
das i2c ist so schnell das es die Tastenabfrage nicht beeinflußt.
Timingproblem in der SW? ADC-Kanal abgefragt der gerade i2c machte?
Einzelne kurze Tastendrücke machen keine Probleme. Längere Dauerkontakte
kollidieren dann mit dem I2C-Signal und bringen manchmal den Nano zu
Absturz oder die I2C-Verarbeitung wird dadurch natürlich gestört.
Von daher: es ist eine Krückenlösung. Mann kann die I2C-Ansteuerung
sozusagen "morsen", wie weiter oben schon beschrieben.
Man kann das schon machen, indem die Tasten über Widerstände so
angeschlossen werden, daß an den Pullups immer gültige High-Pegel
anliegen. D.h. die Tasten senken nur auf >=3,5V ab. Dann bleibt der I2C
ruhig.
Ich würds aber trotzdem nicht machen.
Wenn man eh I2C benutzt, würde ich die Lösung mit dem PCF8574/A
präferieren. Das ergibt auch ein einfaches Layout und keine zusätzliche
Komponenten, da interne Pullups.
Peter D. schrieb:> da interne Pullups.
Ist richtig, aber Vorsicht mit den Internen Pullups,
Es gibt diversi Taster die bei µA nach einer Gewissen Zeit Oxide
bekommen und dann nicht mehr richtig tun.
Das hängt damit zusammen das der PCF8574 keine wirkliche Pullups hat
sondern man kann sagen "µAmpups" ....LOL....
und die haben nur 100µA was für sehr viele Taster einfach zu wenig ist
;-)
Ein Vorteil ist aber der INT der den Chip macht wenn du den Verwendest,
ersparst du dir das cyclische Abfragen ;-)