Zwei Arduinos Daten über Analog Pin senden?


7

Ich möchte Arduino A erlauben , einen konstanten Wert an Arduino B zu senden .

Ich spüre, dass etwas an meinem Ansatz von Natur aus nicht stimmt, aber ich kann nicht herausfinden, was es ist.

In der folgenden Abbildung sehen Sie, wie Arduino A seinen analogen Pin 0 auf OUTPUT setzt und alle 500 ms einen Wert 2 schreibt. Auf Arduino B haben wir Analog Pin 0 als INPUT gesetzt , um Daten zu empfangen und an Serial zu drucken. Die GND- Pins beider Arduinos sind ebenfalls verbunden.

Wenn dieses Setup ausgeführt wird, empfängt Arduino B ständig Daten in Form einer dreistelligen Nummer, beginnend mit 3XX. Ich fange an zu glauben, dass dies ein Spannungswert ist.

Was ist an dieser Idee von Natur aus falsch?

Geben Sie hier die Bildbeschreibung ein


Haben Sie auch versucht, die Erdungsstifte miteinander zu verbinden?

@Kynit: Ja, die GND-Pins waren verbunden (vergessen, sie zu zeichnen).

Nein, ich lebe nicht in der EE-Welt, aber ich kann es versuchen! Hervorragende Antworten hier, ich versuche alles zu absorbieren. Wird bald aktualisiert.
Lucidgold

@lucidgold Die Zusammenfassung am Anfang meiner Antwort sagt Ihnen genau, was zu tun ist. Der Rest sagt dir warum.
Russell McMahon

Antworten:


9

Diese Antwort liefert sowohl Arduino-spezifisches Wissen als auch allgemeines elektrisches Wissen - beide sind (leider) für eine gute Lösung notwendig.


Zusammenfassung

So führen Sie eine Arduino-Analog-Analog-Übertragung durch:

  • Verwenden Sie analogWrite (Pin, Wert) für einen gültigen digitalen Pin (siehe unten).

  • Verwenden Sie analogRead (Pin) an einem gültigen analogen Eingangspin.

  • Schließen Sie einen Vorwiderstand zwischen den beiden Pins an - sagen wir 10k.
    Stellen Sie einen Kondensator vom Analogeingang auf Masse, z. B. 100 nF bis 10 uF.

Die R & C fungieren als Tiefpassfilter, um die PWM in DC umzuwandeln.
Details unten.


Arduino-Analogstifte sind NUR für Analogeingänge vorgesehen, nicht für Analogausgänge.
Wenn Sie also versuchen, einen analogen Ausgang über einen analogen Pin zu betreiben, ist Ihr Versuch zum Scheitern verurteilt.

Arduino analogWrite (Pin, Wert) funktioniert nur mit DIGITAL-Pins und dann nur mit der Teilmenge der digitalen Pins, die PWM-fähig sind. Dies sind typischerweise digitale Pins 3 5 6 9 10 11.

"analogWrite (Pin, Wert) erzeugt, wie andere gesagt haben - ein PWM-Signal - Rechteckwellen von Schiene zu Schiene mit einem Markierungsraumverhältnis, das so variiert, dass sich der mittlere Gleichstromwert ändert. Für ein 5-V-System =
V_DC_mean ~~ = Wert / 256 x 5 V.
Wobei 'Wert' von analogWrite kommt (Pin, Wert)

Um die PWM in ausreichend guten Gleichstrom umzuwandeln, wird ein Tiefpassfilter mit einem Grenzwert etwas unterhalb der PWM-Bildrate benötigt. Die AFAIK Arduino PWM-Bildrate beträgt ca. 800 Hz - daher sind die Komponenten normalerweise höher. Ein einfacher RC-Filter, bei dem R x C sinnvollerweise mehr als 0,001 S beträgt, beginnt zu funktionieren. Größere RC ist glatter, aber mit Sekundäreffekten. Die Verwendung einer 10-uF-Keramikkappe und eines 10-k-Widerstands ist wahrscheinlich in Ordnung. 10 uF x 10 k = 0,1 S. 1uF und 1k = 0,001 s = marginal. Eine Elektrolytkappe kann verwendet werden, aber der Leckstrom kann die Genauigkeit geringfügig beeinträchtigen. Damit -


Von irgendwo im Arduino-Land (unbekannt) habe ich das folgende Material kopiert.
Dies ist NICHT in der Basisreferenz enthalten, sollte es aber sein.

  • Schreibt einen Analogwert (PWM-Welle) in einen Pin. Kann verwendet werden, um eine LED mit unterschiedlichen Helligkeiten zu beleuchten oder einen Motor mit verschiedenen Geschwindigkeiten anzutreiben. Nach einem Aufruf von analogWrite () erzeugt der Pin eine stetige Rechteckwelle des angegebenen Arbeitszyklus bis zum nächsten Aufruf von analogWrite () (oder eines Aufrufs von digitalRead () oder digitalWrite () auf demselben Pin). Die Frequenz des PWM-Signals an den meisten Pins beträgt ungefähr 490 Hz. Auf der Uno-Karte und ähnlichen Karten haben die Pins 5 und 6 eine Frequenz von ungefähr 980 Hz. Die Pins 3 und 11 des Leonardo laufen ebenfalls mit 980 Hz.

    Auf den meisten Arduino-Boards (mit ATmega168 oder ATmega328) funktioniert diese Funktion auf den Pins 3, 5, 6, 9, 10 und 11. Auf dem Arduino Mega funktioniert sie auf den Pins 2 - 13 und 44 - 46. Älteres Arduino Karten mit einem ATmega8 unterstützen nur analogWrite () an den Pins 9, 10 und 11.

    Der Arduino Due unterstützt analogWrite () an den Pins 2 bis 13 sowie die Pins DAC0 und DAC1. Im Gegensatz zu den PWM-Pins sind DAC0 und DAC1 Digital-Analog-Wandler und fungieren als echte Analogausgänge.


3

analogWrite()auf dem Uno gibt eigentlich kein analoger Wert aus. Es gibt eine PWM-Welle aus, deren Durchschnitt diesem Wert entspricht. Wenn Sie daraus einen echten Analogwert machen möchten, müssen Sie ihn einem Tiefpassfilter unterziehen, um die Komponenten zu entfernen, die ihn stattdessen zu einer PWM-Welle machen.


Was ist das "Tiefpassfilter"?

Ein Tiefpassfilter schneidet die hohen Frequenzen ab (dh die quadratischen Wellenbits von PWM). Google es oder schau dich auf dieser Seite um - es gibt unzählige Beispiele.

Dies ist kaum einzigartig für Arduino / ATmega; Nur wenige Mikrocontroller enthalten echte DACs, mit Ausnahme von Sigma-Delta-Blöcken, die speziell auf Audio zugeschnitten sind.
Chris Stratton

2

Wenn Sie einen konstanten Wert von Arduino A an Arduino B senden möchten, können Sie SoftwareSerial ganz einfach verwenden.

Angenommen, Sie verwenden Arduino Uno - Sie können die Pins 2 und 3 für SoftwareSerial verwenden (siehe http://arduino.cc/en/Reference/SoftwareSerial ), welche Pins für welches Gerät unterstützt werden.

Verbinden Sie Pin 2 und 3 von Arduino A mit Pin 3 und 2 von Arduino B. Sie können beliebige Daten zwischen den beiden Arduinos senden, indem Sie jeweils eine Skizze wie die folgende hochladen. Sie können ein Programm wie CoolTerm verwenden, um einen "SerialMonitor" für jedes Arduino zu öffnen (mit der Arduino-IDE können Sie jeweils nur einen Monitor öffnen).

Der Vorteil dieses Ansatzes gegenüber der Verwendung von AnalogWrite / AnalogRead besteht darin, dass Sie mit AnalogRead nur 1024 Werte erhalten können, die auf der Spannung basieren. Mit SoftwareSerial können Sie beliebige Daten senden.

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup() {
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);

    mySerial.begin(9600);

    Serial.begin(9600);
 }

void loop() {

    if ( mySerial.available() )
    {
         while ( mySerial.available() )
             Serial.write(mySerial.read());

         Serial.println();
    }

    if ( Serial.available() )
    {
        delay(5);

        while ( Serial.available() )
            mySerial.write( Serial.read() );
    }

}

0

Wie oben erwähnt, funktioniert die Verwendung von analogWrite nicht. (Ich nehme an, Sie könnten das vermeintliche analoge Signal mit einer schnellen Schleife abtasten und das Tastverhältnis messen ...)

Warum nicht SoftwareSerialDaten zwischen den beiden Arduinos senden?

Es handelt sich um eine Bibliothek, die eine weitere serielle Schnittstelle vollständig in Software erstellt, sodass sie unabhängig vom Haupt-UART am USB-Anschluss ist.

Es ist bereits Teil der IDE und einfach zu verwenden. Der Demo-Code auf der Hilfeseite funktioniert bereits für Sie und überträgt alle Zeichen von der seriellen USB-Schnittstelle zur seriellen Software-Schnittstelle.


AnalogWrite ist vollkommen in Ordnung, solange ein einfacher 1 x Widerstand und 1 x Kondensatorfilter hinzugefügt werden (siehe meine Antwort). Es kann gute Gründe geben, Analog zu verwenden, was hier nicht ersichtlich ist.
Russell McMahon

0

Wie andere bereits betont haben, wird Ihr ursprünglicher Vorschlag nicht funktionieren.

Sie könnten einen PWM-Ausgang und einen Filter verwenden, der möglicherweise funktioniert (Sie benötigen einen ziemlich großen Kondensator und / oder Widerstand). Die Eingabe am anderen Ende wäre nur eine Annäherung an die Ausgabe (Sie könnten basierend auf detaillierten Kenntnissen der Komponentenwerte und -frequenzen berechnen). Abhängig von der Geschwindigkeit, mit der sich der Wert ändert, erhalten Sie möglicherweise bei jedem Lesevorgang unterschiedliche Werte.

Es gibt bessere Wege. Wie vorgeschlagen, funktioniert seriell (abhängig von anderen Faktoren entweder Hardware oder Software) und ist wahrscheinlich am einfachsten. Sie können jedes der gängigen Kommunikationsprotokolle (I²C oder SPI) verwenden oder sogar Werte über IP senden.


0

Das Analog In macht genau das, was es sagt - es liest nur analoge Spannungspegel (tastet sie ab).

Bei Verwendung von AnalogWrite (0,2) wird Pin A0 in Analog In nicht zur Ausgabe der Spannung von 2 * AVCC / 1024 verwendet, sondern der Pin D0 wird dazu verwendet. (Den meisten D0-Pins auf Arduino-Karten ist kein PWM-Ausgang zugeordnet, daher ist das Verhalten undefiniert.) In der Zwischenzeit unternimmt Ihr A0 nichts. (Ich vermute, es ist schwebend / nicht verbunden, daher der 3xx-Wert. Könnte das Datenblatt überprüfen, um sicherzugehen.)

Was sollen wir stattdessen tun? Verbinden Sie zunächst den A0 von Arduino B mit dem PWM-Pin von Arduino A. Wenn Sie Uno verwenden, können Sie eine Verbindung zu einem der Pins 11,10,9,6,5,3 herstellen. Dann können Sie den Code verwenden:

int PWMPin = 11; int SignalLvl = 2; analogWrite (PWMPin, SignalLvl);

Probieren Sie es aus. Und du wirst sehen, dass es funktioniert ... irgendwie.

Aber dann gibt es ein Problem. Ihre Messwerte werden nah an dem sein, was Sie wollen, aber ziemlich unberechenbar. Der Grund ist teilweise, dass analoge Signale sehr unzuverlässig sind und mit Rauschen gefüllt sind. Der Hauptgrund ist jedoch, dass Arduinos analogWrite eigentlich NICHT als analoger Signalausgang ausgelegt ist. Es handelt sich um eine PWM, die GND- und AVcc-Pegel in variablen Zeiträumen mit hoher Geschwindigkeit ausgibt, sodass sie sich dem gewünschten Spannungspegel annähert, wenn sie gemittelt wird.

Wenn Sie damit experimentieren möchten, können Sie einen Widerstand und einen Kondensator an den Ausgang anschließen und so ein Tiefpassfilter erstellen. (Hier sind weitere Informationen: http://provideyourown.com/2011/analogwrite-convert-pwm-to-voltage/ )


Nach alledem denke ich, dass die meisten von uns die Frage stellen möchten: Gibt es einen Grund, warum Sie Daten analog senden möchten? Analoge Signale sind anfällig für Rauschen. Wenn die Datentreue von entscheidender Bedeutung ist, verwenden Sie am besten die serielle Kommunikation, wie in den meisten Antworten hier hervorgehoben.

Der Einfachheit halber schlage ich I2c vor, das nur 2 Drähte für die Kommunikation verwendet. Wenn Geschwindigkeit von entscheidender Bedeutung ist (z. B. das Schreiben auf 10.000 Datenbytes pro Sekunde), können Sie SPI oder sogar parallele Kommunikation ausprobieren.

Hoffe das hilft und viel Glück!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.