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.
nur so zur Ergänzung: I²C schaltet die Pins regelmäßig zwischen Input und Output um.
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 ?
@Martin, wie sind denn die Tasten angeschlossen? Analog 2 pro Pin oder als 4x4 Matrix? Mit was sind die anderen Pin's so belegt? Sascha
Wenn man eine Software I²C Library benutzt (a la Peter Fleury), kannst du dir die Pins für den Bus frei wählen.
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.
Warum verwendest du nicht noch freie Pins für I²C? bspw D12 D13?
Ich nutze die interne LED an D13 sowie TX und RX für den seriellen Monitor. Der einzige freie Pin ist der D12 :-(
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 ;-)
:
Bearbeitet durch User
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.
1 | //-------------------------------------------------------------------------------------------------------
|
2 | void Relais (byte nr, char* Zielposition) |
3 | //-------------------------------------------------------------------------------------------------------
|
4 | // Schaltet das Relais der Servo-Nummer entsprechend der Zielposition (A/B) ein oder aus
|
5 | {
|
6 | if (Relais_Platine) |
7 | {
|
8 | if ( (Zielposition == "A" && Relaissteuerung [nr] == 1) || (Zielposition == "B" && Relaissteuerung [nr] == 2)) |
9 | {
|
10 | Extension.digitalWrite(Relais_pins[nr], HIGH); |
11 | }
|
12 | else
|
13 | {
|
14 | Extension.digitalWrite(Relais_pins[nr], LOW); |
15 | }
|
16 | Wire.end (); |
17 | |
18 | }
|
19 | }
|
Gibt´s den Wire.end Befehl überhaupt offiziell?
Martin schrieb: > Anbei mal der Schaltplan. 2 Taster pro analog-Input http://www.avr-asm-tutorial.net/avr_de/apps/tasten_schalter_adc/tasten/tasten.html Mach das halt so, dann hast Du die Analogports frei.
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
Mit der Lösung kannst du dann über die Tasten I2C-Befehle absetzen. Aber das war nicht der Plan, oder? LG, Sebastian
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.
:
Bearbeitet durch User
schau mal: https://learn.adafruit.com/16-channel-pwm-servo-driver/using-the-adafruit-library ist nur ein Besipiel
Patrick L. schrieb: > Nur Frage kann der die Frequenz, die für Servos geeignet ist? Wenn das nicht so wäre, würde er wohl kaum als Servo-Controller verkauft. https://www.amazon.de/AZDelivery-PCA9685-Servotreiber-Arduino-Raspberry/dp/B07CRDCP8V
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 :-)
:
Bearbeitet durch User
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.
Martin schrieb: > Für eine Servosteuerung mit einem Nano verwende ich 16 Tasten an den > analogen Inputs A0 - A7. Hä? 16 Tasten geht als Matrix mit 8 Widerständen an einem Analogeingang. Oder mit 4*4 digitalen Pins an einem PCF8574/A. Beitrag "Tastenmatrix auslesen über nur 2 Leitungen"
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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 ;-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.