Forum: Mikrocontroller und Digitale Elektronik Arduino: abwechselnde Verwendung von A4/A5 als analoger Input und I2C


von Martin (Gast)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

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.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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.

von STK500-Besitzer (Gast)


Lesenswert?

nur so zur Ergänzung: I²C schaltet die Pins regelmäßig zwischen Input 
und Output um.

von Martin (Gast)


Lesenswert?

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.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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 ?

von Sascha W. (sascha-w)


Lesenswert?

@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

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wenn man eine Software I²C Library benutzt (a la Peter Fleury), kannst 
du dir die Pins für den Bus frei wählen.

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

Warum verwendest du nicht noch freie Pins für I²C? bspw D12 D13?

von Martin (Gast)


Lesenswert?

Ich nutze die interne LED an D13 sowie TX und RX für den seriellen 
Monitor.
Der einzige freie Pin ist der D12 :-(

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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
von Martin (Gast)


Lesenswert?

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?

von Taster (Gast)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

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).

von Wolfgang (Gast)


Lesenswert?

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?

von Martin (Gast)


Lesenswert?

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!

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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?

von Wolfgang (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

Mit der Lösung kannst du dann über die Tasten I2C-Befehle absetzen. Aber 
das war nicht der Plan, oder?

LG, Sebastian

von besserwisser (Gast)


Lesenswert?

nimm doch einen PCA9685 für die Servos, dann werden 6 pins frei und du 
kannst 16 Sevos ansteuern.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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
von besserwisser (Gast)


Lesenswert?


von Stefan F. (Gast)


Lesenswert?

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

von Axel R. (axlr)


Lesenswert?

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.

von PittyJ (Gast)


Lesenswert?

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'.

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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
von Gerhard O. (gerhard_)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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
von Martin (Gast)


Lesenswert?

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!

von Peter D. (peda)


Lesenswert?

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.

von Achim H. (pluto25)


Lesenswert?

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?

von Martin (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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
von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

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
Noch kein Account? Hier anmelden.