Hallo Leute,
ich habe folgendes Problem,
ich möchte meinen Arduino Uno mit dem AD5272 Digitalpotentiometer über
I2C verbinden. Über den Arduino I2C Portscanner sketsch hat das schon
funktioniert, und somit kenne ich die Adresse: 0x2c
jetzt komme ich aber irgendwie nicht weiter
1
#include<Wire.h>
2
3
voidsetup()
4
{
5
Wire.begin();// join i2c bus (address optional for master)
6
Serial.begin(9600);// start serial for output
7
}
8
9
byteval=0;
10
voidloop()
11
{
12
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
13
Wire.write(byte(val));
14
Wire.endTransmission();// stop transmitting
15
Wire.requestFrom(44,6);
16
17
while(Wire.available())// slave may send less than requested
18
{
19
charc=Wire.read();// receive a byte as character
20
Serial.print(c);// print the character
21
}
22
23
val++;// increment value
24
if(val==100)
25
{
26
val=0;// start over from lowest value
27
}
28
delay(10);
29
}
Das ist der Programmcode, ich möchte erstmal das der Widerstand vom Poti
erhöht wird, und das ich diesen dann über den Seriellen Monitor von der
Arduino IDE auslese, welcher Wert gerade eingestellt ist.
Aber raus bekomme ich nur das:
(((000888@@@HHHPPPXXX```hhhpppx x x
€"€"€"ˆ$ˆ$ˆ$�&�&�&˜(˜(˜( * * *¨,¨,¨,°.°.°.¸0¸0¸0À2À2À2È4È4È4Ð6Ð6Ð6Ø8Ø8Ø8
à:à:à:è<è<è<ð>ð>ð>ø@ø@ø@
(In einer Zeile)
Aber wie bekomme ich die Werte in Zahlen ?
Danke
Wire.endTransmission() liefert einen Status, den würd ich mir mal
ansehen.
> Returns>> byte, which indicates the status of the transmission:>> 0:success> 1:data too long to fit in transmit buffer> 2:received NACK on transmit of address> 3:received NACK on transmit of data> 4:other error
MfG Klaus
Klaus schrieb:> Wire.endTransmission() liefert einen Status, den würd ich mir mal> ansehen.
Wie kann ich den bekommen ?
1
byteresult;
2
byteval=0;
3
voidloop()
4
{
5
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
6
Wire.write(byte(val));
7
Wire.endTransmission();// stop transmitting
8
Wire.requestFrom(44,6);
9
10
while(Wire.available())// slave may send less than requested
11
{
12
charc=Wire.read();// receive a byte as character
13
Serial.print(c);// print the character
14
}
15
16
val++;// increment value
17
if(val==100)
18
{
19
val=0;// start over from lowest value
20
}
21
delay(100);
22
23
result=Wire.endTransmission();
24
Serial.print(result);
25
}
Ich habe den Code hier erweitert um
byte result;
...
result = Wire.endTransmission();
Serial.print(result);
Aber ich bekomme immer noch seltsame Zeichen angezeigt :(
Du bekommst von dem Digitalpotentiometer byte-Werte deklarierst sie aber
als char. Mit Serial.print() schreibst du diese dann. Die Komischen
Zeichen sind "Steuerzeichen" die den Werten entsprechen. Du musst die
byte-Werte erstmal in ein sinnvolles Datenformat umwandeln und dann
ausgeben.
Karl schrieb:> Du bekommst von dem Digitalpotentiometer byte-Werte deklarierst sie aber> als char. Mit Serial.print() schreibst du diese dann. Die Komischen> Zeichen sind "Steuerzeichen" die den Werten entsprechen. Du musst die> byte-Werte erstmal in ein sinnvolles Datenformat umwandeln und dann> ausgeben.
Das bekomme ich heraus, wenn ich byte anstatt char wähle.
Wie wandle ich denn die Werte um :( ?
Ich bekomme zwar die Meldung, dass das Digital Poti mit dem I2C
Portscanner Sketsch gefunden wurde, also liegt es nicht an der
Testschaltung.
Kann mir jemand einen Code zeigen, der Daten vom Arduino an das Poti
sendet und diese von dem Poti wieder beim Arduino empfangen werden und
dargestellt werden ?
Danke
Hast du mal ins Datenblatt geguckt? So wie ich das lese, kannst du nicht
einfach ein Byte schreiben und erwarten, dass passiert was du wolltest.
Probier mal:
1
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
2
Wire.write(1<<2 | val>> 8) //Write contents of serial register data to RDAC.
3
Wire.write(val & 0xff);
4
Wire.endTransmission(); // stop transmitting
5
6
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
7
Wire.write(1<<3) //Read contents of RDAC wiper register.
8
Wire.write(0);
9
Wire.endTransmission(); // stop transmitting
10
11
Wire.requestFrom(44, 2);
12
while(Wire.available()) // slave may send less than requested
13
{
14
byte c = Wire.read(); // receive a byte as character
15
Serial.print(c); // print the character
16
}
und du hast 10 Bit zur Verfügung oder? Dann sollte val auch nicht byte,
sondern größer sein...
Ok, danke Mathias,
jetzt bekomme ich zumindest zahlen ;)
Aber was sind das für werte und wie bekomme ich diese ?
Am wiper kann ich mit dem Multimeter nichts messen, weder Widerstand
noch Spannungsänderung (Wiper Pin messe ich 4,8V gegen Masse)
Die ersten zwei Bits werden ignoriert (x), dann kommen 4 command Bits
(c), dann 10 Daten bits (d). Macht zusammen 16 Bits, das sind 2 Bytes.
Allgemein kannst du dann folgendes nutzen:
1
Wire.write(0bcccc<<2|((val>>8)&0b11))//Write contents of serial register data to RDAC.
2
Wire.write(val&0xff);
Das "<<2" shiftet die Bits um zwei nach links. Also aus 0bcccc wird
0bcccc00. Das "(val>> 8)&0b11" gibt dir Bit 9&10 von val. "|" fügt dann
beide teile zusammen. "val & 0xff" schneidet das untere Byte von val ab.
Gibt dir also die letzten 8 Bits von val.
Wenn man noch nie mit Binärdaten gearbeitet hat, dann guck dir mal die
"Bitwise Operators" auf arduino.cc an.
Mathias schrieb:> Wire.write(0bcccc<<2 | ((val>> 8)&0b11)) //Write contents of serial> register data to RDAC.> Wire.write(val & 0xff);
Die Arduino IDE nimmt den code nicht an
error: invalid suffix "bcccc" on integer constant
invalid suffix "bcccc" on integer constant
Und wie sorgt das nun dafür das sich der Widerstand ändert?
Ich messe mit meinem Multimeter an dem Wiper Pin keine Änderung :(
>Wire.beginTransmission(44);// transmit to device #44 (0x2c)
2
>Wire.write(0x1c);
3
>Wire.write(0x02);
4
>Wire.endTransmission();// stop transmitting
5
>
ok, danke ^^ das hat gefehlt.
Mein Code sieht nun so aus:
1
#include<Wire.h>
2
3
voidsetup()
4
{
5
Wire.begin();// join i2c bus (address optional for master)
6
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
7
Wire.write(0x1c);
8
Wire.write(0x02);
9
Wire.endTransmission();// stop transmitting
10
11
}
12
13
voidloop()
14
{
15
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
16
Wire.write(0b00000111);
17
Wire.write(0b11111111);
18
Wire.endTransmission();// stop transmitting
19
delay(5000);
20
21
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
22
Wire.write(0b00000100);
23
Wire.write(0b00000000);
24
Wire.endTransmission();// stop transmitting
25
delay(5000);
26
}
Ich kann mit dem Multimeter sehen, wie der Widerstand immer hin und her
schaltet 0 und max.
Aber wenn er bei 0 ist, dann blinkt das Multimeter in dem abstand wie
lang der delay dauert (5 sekunden, 5c blinken)
Kannst du mir das erklären ?
Ähh nö, was blinkt da?
Mit der obigen setup, könnte übrigens auch wieder mein erster Code
funktionieren
Beitrag "Re: AD5272 mit Arduino über I2C verbinden"
(Ich bin dann übrigens auch gleich weg, mit Glück gucke ich morgen
nochmal rein.)
Petr t. schrieb:> Über den Arduino I2C Portscanner sketsch hat das schon funktioniert, und> somit kenne ich die Adresse: 0x2c
Du verwendest einen "Portscanner", um die Adresse zu raten, die du mit
einem halben Blick ins Datenblatt gefunden hättest? Vorgehensweisen
gibt's.
Die Lektüre des DB hätte dir überhaupt diesen ganzen Thread ersparen
können.
Petr t. schrieb:> Wire.beginTransmission(44); // transmit to device #44 (0x2c)
Wenn du dokumentieren möchtest, dass die so mühsam ermittelte Adresse
0x2c ist, warum schreibst du dann nicht 0x2c in den Code statt das als
44 reinzuklimpern und einen ansonsten überflüssigen Kommentar zu
bemühen?
Malte S. schrieb:> Wenn du dokumentieren möchtest, dass die so mühsam ermittelte Adresse> 0x2c ist, warum schreibst du dann nicht 0x2c in den Code statt das als> 44 reinzuklimpern und einen ansonsten überflüssigen Kommentar zu> bemühen?
Ich war mir, zum Anfang als ich den Code genommen habe nicht sicher ob
das geht, jetzt weiß ich es ;)
Mathias schrieb:> Ähh nö, was blinkt da?
Beim anlegen des Messklemmen des Multimeters an den Wiper und den Masse
Pin des Digi Potis ist er hochohmig (für 5 sekunden, siehe Programmcode)
und dann fällt der Wert sofort auf 0 Ohm, blinkt dann 5x kurz auf und
wird dann wieder hochohmig.
Mathias schrieb:> Mit der obigen setup, könnte übrigens auch wieder mein erster Code> funktionieren> Beitrag "Re: AD5272 mit Arduino über I2C verbinden"
Das Probiere ich morgen, der Arduino liegt auf der Arbeit ;)
Malte S. schrieb:> Du verwendest einen "Portscanner", um die Adresse zu raten, die du mit> einem halben Blick ins Datenblatt gefunden hättest? Vorgehensweisen> gibt's.
Na im Datenblatt habe ich ja die Tabelle mit den jeweiligen Pin
belegungen gefunden. Je nachdem welcher der Pin´s an Masse oder Vdd ist,
gibt es dementsprechend eine andere Adresse.
Den Portscanner habe ich nur benutzt um zu prüfen, das die I2C
Verbindung funktioniert, der Arduino das Digi Poti am Bus erkennt und
mit der Adresse des Datenblatts übereinstimmt.
Das ganze Datenblatt zu lesen hätte ich machen können, aber wenn nicht
ich, dann wäre irgendwann jemand anderes gekommen um diese Fragen zu
stellen :)
Morgen werde ich weiter daran arbeiten und schauen wie weit ich mit dem
Teil komme.
Auch wenn ich dir wahrscheinlich eh nicht helfen kann, aber kannst du
"blinkt kurz" anders erklären als "blinkt kurz"? Wird das immer kurz
hochohmig oder was?
Vielleicht ist "das Multimeter blinkt" auch ein normaler
elektrodingens-Begriff, den ich einfach nicht kenne...
Mathias schrieb:> "blinkt kurz" anders erklären als "blinkt kurz"? Wird das immer kurz> hochohmig oder was?
Also man muss sich das wie ein Impuls vorstellen, es zeigt, wenn bei 0
Ohm, daurend die 0 Ohm an, aber immer wenn eine Sekunde vergangen ist,
gibt es sowas wie ein impuls und es wird für paar milisekunden 0 KOhm
angezeigt und dann wieder 0 Ohm und dann geht das wieder von vorne los.
1
{
2
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
3
Wire.write(0b00000111);// Teil1
4
Wire.write(0b11111111);
5
Wire.endTransmission();// stop transmitting
6
delay(5000);
7
8
Wire.beginTransmission(44);// transmit to device #44 (0x2c)
9
Wire.write(0b00000100);// Teil2
10
Wire.write(0b00000000);
11
Wire.endTransmission();// stop transmitting
12
delay(5000);
13
}
Bei dem Code habe ich mich jetzt soweit eingelesen und auch verstanden
warum es so getrennt ist.
Aber warum machst du "0b" dann kommen die 2 bits die ignoriert werden
(warum eigentlich?), dann die 4 Kommando bits und dann die Datenbits.
Aber warum kann ich den Wert, in Teil2 nicht ändern, ich möchte ja in
binär mir den Widerstandswert einstellen.
Also müsste es doch so aussehen:
Wire.write(0b00000100);
Wire.write(0b00010000); // Wert wäre 16 (Von rechts 1,2,4,8,16)
Aber das geht bei mir nicht, was habe ich falsch gemacht ?
"...Aber das geht bei mir nicht.." heißt was konkret? Was misst du dann
mit dem Multimeter? Probier mal
1
Wire.write(0b00000110);
2
Wire.write(0b00000000);
Das sollte dann 50% sein.
"0b" sagt dem compiler, hier kommt jetzt eine Binärzahl. Die zwei
ignorierten Bits kommen daher, weil das so im Datenblatt steht. Das
Protokoll braucht nur 14 Bits, weil man aber mit dem uC nur ganze Bytes
(=8Bit) senden kann, müssen irgendwo 2 Müll-Bits sein.
Und die 0kOhm kommen nicht vom Multimeter? Was misst du, wenn du die
Prüfspitzen einfach zusammenhältst? Hast du ansonsten ein Oszilloskop
zur Hand? Oder nimm mal ein anderes Multimeter? Keine Ahnung, ich bin
kein Elektronikfachmann.
Mathias schrieb:> "...Aber das geht bei mir nicht.." heißt was konkret? Was misst du dann> mit dem Multimeter? Probier mal Wire.write(0b00000110);> Wire.write(0b00000000);> Das sollte dann 50% sein.
Ich habe das probiert, aber ich bekomme keinen Wert, es blinkt nur
wieder :(
Ich habe schon das beste Multimeter in der Firma ;) , denke nicht das es
daran liegen kann.
Ok, das mit den Bits habe ich verstanden.
Aber warum funktioniert das nicht, hast du das bei dir probiert ?
Nö, schick mir nen AD5272 und ich probier das mal aus...
Ich glaube ich kann hier nicht mehr helfen, frag den Rest in deinem
anderen Thread:
https://ez.analog.com/thread/69278
Mathias schrieb:> Nö, schick mir nen AD5272 und ich probier das mal aus...>> Ich glaube ich kann hier nicht mehr helfen, frag den Rest in deinem> anderen Thread:> https://ez.analog.com/thread/69278
Ok, trotzdem danke für deine Hilfe, hast mir viel geholfen.
^^
Mathias schrieb:> Wire.beginTransmission(44); // transmit to device #44 (0x2c)>> Wire.write(0b00000110); //Write RDAC 50%> Wire.write(0b00000000);>> Wire.write(0b00001000); //Read RDAC> Wire.write(0b00000000);>> Wire.endTransmission(); // stop transmitting (evtl. erst später> senden?)>>> Wire.requestFrom(44, 2);>> while(Wire.available()) // slave may send less than requested> {> byte c = Wire.read(); // receive a byte as character> Serial.print(c); // print the character> Serial.print(" ");> }> Serial.println("");
Mathias, vielen vielen dank :)
jetzt läuft das Digital Poti, der Widerstand lässt sich vom minimalen
Wert 28,8 Ohm bis 20kOhm einstellen.
Das Problem lag wohl das der Kommando Code 0b00001000 zum auslesen des
RDAC nicht vorhanden war.
Nochmals vielen dank.
Ps. Hier das Foto
Wat? Das soll geholfen haben? Also du hast das ja schon mit nem
Multimeter gemessen, das sollte dann doch nichts mehr ändern...
merkwürdig.
Na was solls, man muss ja nicht immer verstehen warum etwas geht oder
nicht geht, so lange es geht...