Hallo,
prima, dann brauch ich nicht weiter testen. Mache es am WE trotzdem mal ;)
Edit:
SDA ist bei meinem ARDUINO auf High, wenn ich Deinen Code compiliere. Daher die Pegelandler oder den Mega2560 mit 3V3 betreiben.
Druckbare Version
Hallo,
prima, dann brauch ich nicht weiter testen. Mache es am WE trotzdem mal ;)
Edit:
SDA ist bei meinem ARDUINO auf High, wenn ich Deinen Code compiliere. Daher die Pegelandler oder den Mega2560 mit 3V3 betreiben.
Beim Mega muss man zwingend die dort vorhandenen internen Pullups auf 5V disablen; dazu 2 Zeilen in twi.c auskommentieren:
file: twi.c ( path: Arduino\hardware\arduino\avr\libraries\Wire\utilit y )
// activate internal pullups for twi.
// digitalWrite(SDA, 1);
// digitalWrite(SCL, 1);
ps
(edit: )
Ja, du hast Recht!
Der Raspi hat eingebaute Pullups, die auf 3.3V hochziehen, aber beim Mega verbleiben 10k Board-Pullups, die machen es grenzwertig, auch wenn man die internen disabled. Tatsächlich sind beim mega Levelshifter sicherer!
Hallo,
ich habe es auskommentiert. Die Pullups sind aber immer noch aktiviert. Evtl. was auf dem Board.?. Meiner ist von Sainsmart, MEGA2560. Suche ich morgen weiter, jetzt kommt Wheelers Dealers :)
Dein Programm läuft soweit, bis man kurz mal die Verbindung trennt. Dann syncen die nicht mehr auf Beginn des Telegramms. Auch das werde ich mir mal näher ansehen.
Hm - bisher habe ich nur den Due beutzt - aber ja, tatsächlich, er hat 2 im Prozessor und 2 auf dem Board. Die einen lassen sich disablen, die anderen nicht.
Angeblich sollen aber die verbleibenden wegen Ihres höheren Widerstandes dann nicht mehr ins Gewicht fallen :
http://www.varesano.net/blog/fabio/h...nd-scl-i2c-bus
psZitat:
internal pullups
Submitted by as3.1415rin (not verified) on Thu, 2012-07-19 21:39.
as far as I understand, the 5V/3.3V is the only reason to switch them off. if that's not the point, internal + external pullups should be fine, then the activated internal ones are not doing any damage
(edit: )
Ja, du hast Recht!
Der Raspi hat eingebaute Pullups, die auf 3.3V hochziehen, aber beim Mega verbleiben 10k Board-Pullups, die machen es grenzwertig, auch wenn man die internen disabled. Tatsächlich sind beim mega Levelshifter sicherer!
ps,
das mit dem re-syncen stimmt und ist noch nicht gelöst. Ich war jetzt nach dem sleep-Bug erstmal froh, dass es überhaupt schon sehr schnell lief. Ich weiß auch nicht, wie es sonst auf dem Raspi läuft, wenn mal eine i2c-line zu einem Device wie z.B. einem MCP oder PCF zwischenzeitlich ausfällt und dann wieder hergestellt wird. Ein stabiles Protokoll mit re-sync wäre schon wünschenswert. Eventuell könnte man einen Timer mitlaufen lassen, der z.B. nach 100ms time-out sowohl auf dem Master als auch dem Slave i2c resettet und dann neu startet?
habe jetzt genauere Infos aus dem Arduino-Forum:
...Zitat:
On the Arduino Mega 2560 board are pullup resistors of 10k for SDA and SCL. The internal pullup resistors of the ATmega2560 chip are about 50k.
The internal pullup resistors can be disabled in the library, or in the sketch.
It can be done in the sketch, because SDA and SCL are still digital inputs, even if I2C is enabled for those pins. So writing a zero disables the pullup.
Code: [Select]
Wire.begin();
digitalWrite( SDA, LOW);
digitalWrite( SCL, LOW);
Also, ich muss mich berichtigen: gerade die blöden 10k lassen sich nicht disablen, und damlt wird es tatsächlich kritisch.Zitat:
It is the other way around.
The 50k are internal in the ATmega2560 chip and can be disabled.
The 10k are on the Arduino Mega 2560 board and can not be disabled. Perhaps you can try to scratch a pcb trace and work around that 10k.
The Arduino Mega 2560 is the only board with those 10k resistors on the board for I2C. Any other board would be no problem.
Connect 5V with 10k to 3.3V with 1k8. That makes 3.55V
I don't like that, often 3.6V is the limit for 3.3V chips, and this is very close.
Using a dirty trick with a resistor to GND to lower it might also cause trouble. The Arduino Mega board needs 3.5V to see a I2C level as high.
With a level shifter, the Arduino has to pull both sides of the level shifter down. A level shifter has often 10k on both sides.
Total current:
5V with 10k and 10k : 1mA
3.3V with 1k8 and 10k : 2.16mA
Together it is above 3mA, which is specified as the maximum current by the official I2C standard. But that 3mA is not very strict, it will work :)
http://gammon.com.au/forum/?id=10896&reply=5#reply5
My conclusion : Use a level shifter or an other Arduino board.
Hallo,
ja, ich werde auf die Pullups warten. Die sollten demnächst eintrudeln.
Wenn die stören, opfere ich ein USB-Kabel und führe die 5V über eine 3V3 Regelplatine zum ARDUINO.
Das Protokoll habe ich gestern schon bissel bearbeitet, ist aber noch nicht fertig. Zumindest klappt die Sync noch nicht.
Edit:
Danke für die Recherche mit den Pullups. Da sich ein Raspi vor einiger Zeit schon verabschiedet hat, messe ich jetzt immer doppelt und dreifach, bevor ich was verbinde ;)
klasse, wär ja super, wenn wir da was gemeinsam auf die Beine stellen könnten.
Ich hab gestern abend/nacht schon einen älteren Levelshifter bei mir probiert, damit gings nicht. ich hab aber noch einen neueren, ungebrauchten, mal gucken, was der sagt.
heute abend weiß ich mehr...
ps:
wie man i2c buffer_size beim Arduino vergrößert, weiß ich zwar, aber nicht wie's beim Raspi geht.
64 bytes wären schön auf beiden Seiten, dann kann man sogar jede menge long-int Encoder-Werte oder floats übertragen...
Haste du da evtl auch ne Idee?
klappt bei mir nicht mit Mega und Levelshifter:
für die ersten 10 bis 30 Arrays werden vom Slave Daten ausgetauscht, dann passiert am Mega plötzlich nichts mehr;
auch der Raspi kriegt keine neuen Daten mehr: i2c tot.
i2cdetect -y l zeigt anschließend keinen i2c-slave mehr an 0x04 an.
Jetzt hab ich noch einen 3. Levelshifter gefunden, da sind aber noch keine Pins dran....: morgen also....Code:pi@raspberrypi ~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Der Raspi-Code muss übrigens noch etwas abgeändert werden, dass er nur dann seine Test-Variable weiterzählt, wenn er vorher einen korrekten Array vom Slave bekommen hat - er ist jetzt schon besser, aber noch nicht 100% ok:
dann alles wieder umgesteckt auf 3,3V Due...:Code:// Raspberry Pi Master code to send/receive byte arrays
// to an Arduino as an I2C slave
//
// ver. 0.002
//
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/ //
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <errno.h>
#include <string.h>
#define MSGSIZE 30
unsigned char calcchecksum( unsigned char array[]) {
int32_t sum=0;
for(int i=2; i<MSGSIZE; ++i) sum+=(array[i]);
return (sum & 0x00ff);
}
int main (void)
{
int fd, i ;
unsigned char test=0;
unsigned char data [MSGSIZE] ;
if ((fd = wiringPiI2CSetup (0x04) ) < 0)
{
fprintf (stderr, "Can't open RTC: %s\n", strerror (errno)) ;
exit (EXIT_FAILURE) ;
}
for (;;)
{
memset(data, 0, sizeof(data) );
data[0]= 0xff; // init for transmission error check
read (fd, data, MSGSIZE) ;
if( data[1] != calcchecksum( data ) ) {
// handle transmission error !
}
else {
printf ("read: ");
for (i = 0 ; i < MSGSIZE ; ++i)
printf (" %3d", data [i]) ;
printf ("\n") ;
delay(10) ;
memset(data, 0, sizeof(data) );
data[5]= test++;
data[0]= 0xff;
data[MSGSIZE-1]= 0x04;
data[1] = calcchecksum( data );
write(fd, data, MSGSIZE) ;
printf ("write: ");
for (i = 0 ; i < MSGSIZE ; ++i)
printf (" %3d", data [i]) ;
printf ("\n\n") ;
delay(10) ;
}
}
return 0 ;
}
fluppt.
- - - Aktualisiert - - -
ps,
im Augenblick re-synced er sogar automatisch:
nach Rausnehmen einer i2c-Leitung stoppt die Transmission auf dem Slave
(blöderweise zählt der Raspi trotzdem weiter...: to do: error handling),
aber nach wiedereinstecken machen Raspi und Arduino wieder ganz normal weiter.
Hallo,
Für so etwas gibt es eigentlich nur eine Ursache: Störungen.
Entweder ist es ein Hardware-Problem, dann muss man am Error-Handlich arbeiten. Es sollte zumindest eine Störungsmeldung auftreten, welche eine Neu-Synchronisation ermöglicht. Wenn die Störung allerdings einen Latch-Up erzeugt, hilft nur Aus/Einschalten :-(
Oder es liegt an der Software. Typische Fehlerquellen sind Interrupts, weil sie ganz einfach das Timing "versauen", der Stack zu klein ist, ein Pointer in die Irre zeigt oder ein Register nicht gerettet/gestört wird.
Vor allem den Stack (Auto Variablen) muss man sich sehr genau ansehen. Zugriffe ausserhalb von Array-Grenzen führen zu sehr lustigen Effekten.
Bei einem meiner ersten Projekte(6502 @1MHz, Assembler) hatte ich im Schnitt 1x in der Wochen einen Programmabsturz. Manchmal, auch wiederholt, schon mach 1-2 Minuten. Die Ursache war dann, dass der Interrupt 1x pro Sekunde für einen Takt fälschlicherweise offen war, Wahrscheinlichkeit 1:1'000'000.
MfG Peter(TOO)
wie gesagt: Tipps aus dem Blauen wieder ins Blaue bingen nichts.........:
Zitat:
Für alle Tipps bin ich natürlich offen, aber der, der sie vorschlägt, müsste schon in der Lage sein, die Verbindung ebenfalls herzustellen und bei sich selber vor Ort zu testen (d.h. er müsste auch einen Raspi und einen Arduino besitzen und sie entsprechend verbinden und seinen eigenen - bzw. unseren gemeinsamen, auf einander abgestimmten - Code testen können).