Go Down

Topic: Problem mit Beispielprogramm für AS3935 Lightning Sensor Breakout (Read 3539 times) previous topic - next topic

peter_de

Hallo an alle,

Ich habe ein Problem mit einem ähnlichen des hier  beschriebenen Blitzdetektors.
In dem Artikel wird dieses Beispielprogramm erwähnt welches ich verwende.

Angeschlossen ist dieses Breakout-Board über I2C an einen Arduino UNO gemäß Figure 13 aus diesem Datasheet.
AS3935       UNO
Vdd          +5V
GND          GND
CS           GND
SI           +5V
IRQ          Pin 2
CLK          A5 (10k Pullup)
MISO         GND
MOSI         A4


Im Beispielprogramm habe ich Zeile 7 geändert:
aus "#define IRQ_PIN 8" wurde "#define IRQ_PIN 2". weil mit Pin 8 der Oszillatorableich nicht funktionierte.
geändert wurde auch Zeile 102:
aus "PCintPort::attachInterrupt(IRQ_PIN, pinchange_isr,RISING);" wurde "attachInterrupt(IRQ_PIN, pinchange_isr,RISING);" wegen Mecker vom Compiler "error: 'PCintPort' has not been declared".

Jetzt zum Problem:
Im Beispielprogramm wird in Zeile 175 über AS3935_Register_Set schreibend, und in Zeile 199 (342) über AS3935_Register_Read lesend auf die Registeradresse 0x00 des AS3935 zugegriffen.

Beide Aufrufe (lesen und schreiben) führen dazu dass das Programm "hängen bleibt".
Ich erhalte dann keine Ausgaben über den Serial-Monitor mehr.
Wenn ich Zeile 175 und 199 auskommentiere läuft der Sketch durch.

Lesende und schreibende Zugriffe auf die anderen Register (Seite 12 in Datenblatt) funktionieren scheinbar problemlos.

Ich finde leider den Fehler nicht selbst und bitte deshalb hier um Hilfe.
Spinnt evtl. die Wire-Library wenn Registeradresse  0x00 angesprochen wird?

Herzlichen Dank für eure Hilfe
Peter

Kaum macht man Etwas richtig, funktioniert es auch!

Serenifly

#1
Aug 31, 2014, 11:32 pm Last Edit: Sep 01, 2014, 03:03 am by Serenifly Reason: 1
1.)
Das kann daran liegen dass man 0 nicht von NULL unterscheiden kann. 0 kann auch ein Null-Pointer sein und es gibt Wire.write(char*), da die Wire Klasse von der Stream Klasse abgeleitet ist, welche wiederum von Print abgeleitet ist. Dann ist nicht eindeutig welche der überladenen Methoden gemeint ist.

Du kannst mal das probieren:
Code: [Select]

Wire.write((byte)addr);


Compile-Fehler in der Richtung sind normal (" call of overloaded '---' is ambiguous"). Das ist der Grund weshalb in C++11 das nullptr Schüsselwort eingeführt wurde.

Laufzeit Fehler sind dagegen etwas seltsam. Rein nach Standard sollte eine der Integer Methoden aufgerufen werden und nicht write(char*).

2.)
Wenn du sowieso auf Pin 2 bist, würde ich auf die Pin Change Interrupts verzichten und gleich richtige Hardware Interrupts verwenden. Mit der normalen Arduino attachInterrupt() Funktion und 0 als Argument:
http://arduino.cc/en/Reference/AttachInterrupt

uwefed

Hast Du die eingebundenen Bibliotheken?
#include <Wire.h>
#include <PinChangeInt.h>
#include "TimerOne.h"
Grüße Uwe

jurs


Ich finde leider den Fehler nicht selbst und bitte deshalb hier um Hilfe.
Spinnt evtl. die Wire-Library wenn Registeradresse  0x00 angesprochen wird?


Lade Dir einen I2C-Scanner Sketch auf das Board und lasse die verfügbaren I2C-Adressen suchen!
http://playground.arduino.cc/Main/I2cScanner

Wenn der I2C-Scanner nichts findet, hast Du kein funktionierendes I2C-Gerät an Deinem Arduino hängen und brauchst mit einem anderen Sketch erst gar nicht erst irgendwas zu versuchen!

Also was sagt der I2C-Scanner?
Es wurde ein I2C-Gerät gefunden ==> Fehler in der Software
Es wurde kein I2C-Gerät gefunden ==> Fehler in der Hardwareschaltung

peter_de

Hallo an alle und danke für die vielen Tipps.

Ich habe ein paar Dinge ausprobiert.

Erst mal habe ich den I2C-Scanner Sketch geladen.
Ergebnis: "No I2C devices found"

Ich hatte bisher das  Modul mittels Dupont Verbindern direkt mit dem UNO verbunden. Das war etwas unglücklich weil ich einige Pins mehrfach brauchte und sich dies mit den Dupont Verbindern schlecht realisieren lässt.
Dann habe ich die Verdrahtung abgerissen und über ein Breadboard neu aufgebaut.

Nochmal den 2C-Scanner laufen lassen.
Ergebnis: "No I2C devices found"

Das hat mich erst mal verblüfft, ich hatte doch schon mal reale Daten vom Sensor erhalten.

I2C-Scanner Sketch angeschaut und Zeile 48 von
Code: [Select]
for(address = 1; address < 127; address++ )in
Code: [Select]
for(address = 0; address < 127; address++ )geändert.
Ergebnis: I2C device found at address 0x00  !

Dann die drei Librarys auf Vorhandensein geprüft.
Die PinChangeInt.h hat gefehlt, der Comiler nicht gemeckert und ich dachte die gehört zur Grundausstattung der IDE. So kann man sich täuschen.
pinchangeint-v2.19beta.zip heruntergeladen und installiert.

INT-Signal wieder auf Pin8 verdrahtet und Beispielprogramm neu geladen.
Puhh - läuft -freu !!!
Die auskommentierten Zeilen 175 und 199 wieder aktiviert.
Läuft immer noch !!

Dann habe ich nochmal einen Blick in das Datenblatt des AS3935 bezüglich der I2C Adresse geworfen und folgendes gefunden:
Quote
The device addresses for the AS3935 in read or write mode are defined by:
0-0-0-0-0-a1-a0-0: write mode device address (DW)
0-0-0-0-0-a1-a0-1: read mode device address (DR)
Where a0 and a1 are defined by the pins 5 (ADD0) and 6 (ADD1).

a0 und a1 sind bei meinem Board aber nicht herausgeführt. An die Pins 15(a0) und 16(a1) des ICs komme ich auch nicht heran.
Ich nehme an, die liegen auf GND weil sich das Teil an Adr. 0x00 meldet.
Sicher bin ich mir aber nicht, kann auch sein dass die Eingänge offen sind und zufällig auf 0 liegen. Einen Schaltplan vom Breakout-Board habe ich leider nicht gefunden.

Laut Datenblatt wäre die Leseadresse = Schreibadresse +1.
Im gesamten Beispielprogramm wird aber immer nur 0x00, also die Schreibadresse, verwendet.
Wie ist das beim lesen? Ist die Leseadresse bei i2C immer Schreibadresse +1 und macht das die Wire-Library automatisch?

Wegen der Ungewissheit bezüglich der Adresspins bei I2C werde ich das Teil mal über SPI anschließen und testen. Testsketch ist verfügbar.

Den Tipp zur Unterscheidung von 0 und NULL habe ich auch beherzigt, hat aber nichts gebracht.
Um auf die Pin Change Interrupts zu verzichten teste ich nochmal die Hardware Version mit IRQ an Pin2.
Der Aufruf von "timer1_isr()" ist aber nicht Bestandteil der PinChangeInt-Library sondern der TimerOne-Library, oder sehe ich das falsch?

Gruß Peter
Kaum macht man Etwas richtig, funktioniert es auch!

michael_x

Quote
Den Tipp zur Unterscheidung von 0 und NULL habe ich auch beherzigt, hat aber nichts gebracht.


??? 
Hast du ?

0 ist die einzige Zahl, die so wie sie da steht auch ein Zeiger sein könnte, daher ist 
  x.write (0x00) nicht eindeutig, denn es gibt zwei verschiedene Funktionen, die gemeint sein könnten.

Code: [Select]
char * addr = 0;
byte b = 0;

x.write (b); // eindeutig
x.write (addr); // formal richtig, macht etwas ganz anderes,  aber hier natürlich Blödsinn.


Mal abgesehen davon, dass 0 keine Adresse für ein I2C device ist und der Scanner deswegen bei 1 anfängt.


peter_de

Hallo,


Quote
Den Tipp zur Unterscheidung von 0 und NULL habe ich auch beherzigt, hat aber nichts gebracht.


??? 
Hast du ?
...


Im Funktionsaufruf steht doch:
Code: [Select]
void AS3935_Register_Set (byte addr,byte pos,byte length, byte data)
Damit ist die Variable addr doch als byte definiert?
Ich habe aber auch:
Code: [Select]
Wire.write(addr);durch
Code: [Select]
Wire.write((byte)addr);ersetzt.



Quote

...
Mal abgesehen davon, dass 0 keine Adresse für ein I2C device ist und der Scanner deswegen bei 1 anfängt.


Sowas hatte ich schon vermutet. Aber es ist nun leider mal so das das verwendete IC (AS3935) sowohl SPI als auch I2C kann.
An die Pins zur Einstellung der I2C Adresse komme ich aber leider nicht ran, weil sie auf dem Breakout-Board nicht herausgeführt sind. Beide Adresspins liegen scheinbar auf LOW weil sich das Device auf Adr. 0x00 meldet.

Kurzum, das IC kann SPI und I2C aber mit dem vorhandenen Breakout-Board kann ich I2C nicht verwenden.

Gruß Peter
Kaum macht man Etwas richtig, funktioniert es auch!

michael_x

Adresse 0 ist "an alle"
http://www.i2c-bus.org/addressing/general-call-address/ 
Quote
The master cannot detect how many devices are using the message.


Macht daher keinen Sinn für den Scanner, und der Master kann auch nicht erkennen ob etwas passiert ist.


Quote
Damit ist die Variable addr doch als byte definiert?

Ja natürlich, bei Variablen in Funktionsaufrufen passt das nicht, da ist der Datentyp klar.
Beim "Unterschied zwischen 0 und NULL" ging's um feste Werte, dachte ich, sorry. 
Code: [Select]
Serial.write (0); // Fehler, ging aber früher

Go Up