Da kommt nexte Hurde die Pins zwischen D7 und D8 haben keinen 2,54 mm Abstand und sind Versetzt gegenüber A0, A1
Mall genau drauf schauen und die Platine drauflegen
die I2C kabel werden keine 25cm übersteigen,eventuell wenn ich später noch LCDś einbinde werden die kabel 1-1,5m haben,ich habe aber schon modularkabel 2x2 und cat kabel besorgt mit der isolierung sollte es auch über größere strecken funktionieren. die sensor kabel können ich denke bis zu 5m haben.
Dann hast du da ein Problem mit der Spannungsversorgung, nichts anderes.
Die Spannungsversorgung der Sensoren und anderen hat damit nichts zu tun, wenn du alles richtig machst.
Für Mega benutze ich sowas ist bequemer als löten und wen zu wenig Plus oder Minus Pins gibt kommt zusatz Leiste auf Lochraster mit Schraubklemmen,
hab ich auch schon gemerkt. ich weiß nicht ob das gewollt ist aber ich vermute der jenige der das platinen design erstellt hat benutzt ein Rastermaß von 1,27mm (müsste er ja auch wegen dem controller) und hat einfach dummerweise wenn der abstand zwischen den leisten gewollt ist wenn es eine lochrasterplatine gewesen wäre würde ich sagen das er 1 loch anstatt um auf die 2,54mm zu kommen 2 löcher abstand gemacht oder es wird eine werbe strategie sein um zu erschweren das jemand sich seine prototyp platine selbst herstellt und du wenn du unwissend bist davon ausgehst das du die fertigen shields kaufen musst
ich wollte mir für diesen zweck noch die gleiche größe lochrasterplatine noch mal besorgen aber mit einem rastermaß von 1,27mm und hoffe damit das problem zu lösen.
Nein das wurde gemacht um Bastler ärgern anders kann ich mir das nicht vorstellen ![]()
habe ich mir auch schon angeschaut, da ich aber keine smd teile löte,macht es für mich mehr sinn es auf eine rohe lochrasterplatine zu bauen wo ich dann auch ehrheblich mehr "löcher" zur verfügung habe.
Gibts noch etwas preiswerter bei Ali
Datenblätter usw finden sich auf der Herstellerseite:
Wenn Du das auf den Kabel für den I2C Bus beziehst dann irrst Du. Ein I2C BUS hat durch den Kabel eine Kapazität die durch die Pullup-Widerstände nach einem LOW-Bit geladen werden muß.
Grüße Uwe
80$ ist heftig auch wen der Kontroller mit ist, da baue mir die benötige Platinen zum Projekt selber
ok ich schau mal,ich denke mit 1m oder 1,5m müsste ich aber mit den LCDś hin kommen.
danke schon mal, ich hätte freitag noch geschrieben aber da ich neu auf der plattform bin,durfte ich anscheinend nur eine gewisse anzahl an antworten den tag geben.
I2C?
Da bist du tief im Bereich der (kaum lösbaren) Probleme!
Dann sollte der PullUp-Gesamtwiderstand möglichst klein sein, so zwischen 1 und 5 kΩ. Außerdem könntest Du je einen PullUp-Widerstand an jedem Ende vom I²C-Bus plazieren.
Die Taktfrequenz sollte niedrig sein, die üblichen 100 kHz sind gut. Manche Bibliotheken setzen diese Frequenz aber auf 800 kHz und mehr hoch, was zu Problemen führen könnte. Dein Logikanalysator bringt Klarheit.
Da muß man aufpassen, weil manche Variablentypen unterschiedliche Bytezahl haben. Daher verwende ich Typbezeichnungen, wo die Länge eindeutig ist, also uint16_t für 16 Bit bzw. zwei Byte. Das ist für die Anzahl der zu übertragenen Byte wichtig.
Temperaturen können mit den Sensoren nicht sehr genau gemessen werden, weshalb ich die Meßwerte in Zehntelgrad speichern und übertragen würde. Float bringt keinen Gewinn.
Die Temperaturen packt man zusammen mit den Variablen vom Typ bool in eine Struktur.1)
Da die Bibliothek Wire nur einzelne Bytes überträgt, wird parallel zur Struktur noch ein Feld, das auf dieselben Speicher zugreift, vom Typ Byte genutzt. Feld und Struktur müssen die selbe Anzahl Bytes lang sein. Union und Struktur müssen hinsichtlich Länge und Reihenfolge auf Sender- und Empfängerseite identisch sein, nur die Namen können sich unterscheiden.2)
Mega2560 mit zufälligen "Meßwerten":
#include <Wire.h>
const uint8_t I2C_Mega2560 = 0x08;
const uint8_t ANZAHL_TEMP = 6;
const uint8_t ANZAHL_PIR = 2;
const uint8_t ANZAHL_REED = 4;
const uint8_t BYTEZAHL = 2 * ANZAHL_TEMP + ANZAHL_PIR + ANZAHL_REED;
union {
uint8_t bytes[BYTEZAHL];
struct {
uint16_t temp[ANZAHL_TEMP];
bool pir[ANZAHL_PIR];
bool reed[ANZAHL_REED];
};
} tx;
void requestEvent() {
Wire.write(tx.bytes, BYTEZAHL);
}
void setup() {
Serial.begin(9600);
Wire.begin(I2C_Mega2560);
Wire.onRequest(requestEvent);
}
void loop() {
uint32_t jetzt = millis();
static uint32_t vorhin;
const uint32_t intervall = 1000;
if (jetzt - vorhin >= intervall) {
vorhin = jetzt;
for (uint8_t j = 0; j < ANZAHL_TEMP; j++) {
tx.temp[j] = random(150, 550);
}
tx.pir[0] = random(0, 2);
tx.pir[1] = random(0, 2);
for (uint8_t j = 0; j < ANZAHL_REED; j++) {
tx.reed[j] = random(0, 2);
}
}
}
ESP323):
#include <Arduino.h>
#include <Wire.h>
const uint8_t I2C_Mega2560 = 0x08;
const uint8_t ANZAHL_TEMP = 6;
const uint8_t ANZAHL_PIR = 2;
const uint8_t ANZAHL_REED = 4;
const uint8_t BYTEZAHL = 2 * ANZAHL_TEMP + ANZAHL_PIR + ANZAHL_REED;
union {
uint8_t bytes[BYTEZAHL];
struct {
uint16_t temp[ANZAHL_TEMP];
bool pir[ANZAHL_PIR];
bool reed[ANZAHL_REED];
};
} rx;
void setup()
{
delay(500);
Wire.begin();
Serial.begin(115200);
Serial.println("\nStart ...");
}
void loop() {
uint32_t jetzt = millis();
static uint32_t vorhin;
const uint32_t intervall = 1000;
if (jetzt - vorhin >= intervall) {
vorhin = jetzt;
Wire.requestFrom(I2C_Mega2560, BYTEZAHL);
int index = 0;
while ( Wire.available() ) {
rx.bytes[index] = Wire.read();
if (index < BYTEZAHL) index++;
}
Serial.printf("empfangene Bytes: %d\n", index);
for (uint8_t j = 0; j < ANZAHL_TEMP; j++)
{
Serial.printf("Temperatur %u: %4.1f°C\n", j, rx.temp[j] / 10.0);
}
Serial.printf(" PIR 1: %u\n", rx.pir[0]);
Serial.printf(" PIR 2: %u\n", rx.pir[1]);
for (uint8_t j = 0; j < ANZAHL_REED; j++)
{
Serial.printf(" Reed %u: %s\n", j, rx.reed[j] ? "Ein" : "Aus");
}
Serial.println("--------------------");
}
}
Anzeige:
11:47:35.278 -> empfangene Bytes: 18
11:47:35.278 -> Temperatur 0: 31.1°C
11:47:35.278 -> Temperatur 1: 29.5°C
11:47:35.278 -> Temperatur 2: 19.5°C
11:47:35.278 -> Temperatur 3: 15.8°C
11:47:35.278 -> Temperatur 4: 54.7°C
11:47:35.278 -> Temperatur 5: 45.3°C
11:47:35.278 -> PIR 1: 1
11:47:35.278 -> PIR 2: 1
11:47:35.278 -> Reed 0: Ein
11:47:35.278 -> Reed 1: Aus
11:47:35.278 -> Reed 2: Aus
11:47:35.278 -> Reed 3: Ein
11:47:35.278 -> --------------------
Anm.:
-
Der Typ
boolbenötigt unglücklicherweise ein Byte zur Übertragung. Daher wäre es speichersparender, alle digitalen Informationen in nur ein Byte zusammenzufassen. Andererseits werden dafür mehr Programmzeilen benötigt. Solche Dinge muß man im Projektzusammenhang bewerten. -
Anstatt immer die gesamte Struktur zu übertragen, könnte man auch nur einzelne Werte anfordern und senden. Beispielsweise Raumtemperaturen ändern sich nur langsam, während Informationen von digitalen Ein- und Ausgängen schon mal schneller benötigt werden könnten.
-
Referenz printf
32Byte Block größe.
Maximal
union TypePunner // evtl Alignment, Bit und Byte Order beachten
{
struct
{
bool flag: 1 ; // 1 Bit pro bool
signed value: 3; // 2 Bit plus 1 Bit fürs Vorzeichen
unsigned unused: 4; // noch 4 Bit frei im Byte
};
byte asByte;
}; // evtl sinnvoll _attribute__((packed, aligned(4))) (oder ähnlich)
TypePunner test;
void setup()
{
Serial.begin(9600);
test.flag = true;
test.value = -2;
}
void loop()
{
Serial.println(test.flag);
Serial.println(test.value);
Serial.println(test.asByte);
delay(1000);
}
Verstehe ich das richtig, Du stimmst mir zu, ergänzt aber die maximale Anzahl auf 32, weil Wire nur eine Puffergröße von 32 hat?
Leider verläßt mich Leo, soll das Typstampfer heißen?
Das funktioniert:
// Mega2560
#include <Wire.h>
const uint8_t I2C_Mega2560 = 0x08;
const uint8_t ANZAHL_TEMP = 6;
//const uint8_t ANZAHL_PIR = 2;
//const uint8_t ANZAHL_REED = 4;
const uint8_t BYTEZAHL = 2 * ANZAHL_TEMP + 1;
union {
uint8_t bytes[BYTEZAHL];
struct {
uint16_t temp[ANZAHL_TEMP];
struct
{
bool pir1: 1 ; // 1 Bit pro bool
bool pir2: 1 ; // 1 Bit pro bool
bool reed1: 1 ; // 1 Bit pro bool
bool reed2: 1 ; // 1 Bit pro bool
bool reed3: 1 ; // 1 Bit pro bool
bool reed4: 1 ; // 1 Bit pro bool
};
};
} tx;
void requestEvent() {
Wire.write(tx.bytes, BYTEZAHL);
}
void setup() {
Serial.begin(115200);
Serial.println(sizeof(tx));
Wire.begin(I2C_Mega2560);
Wire.onRequest(requestEvent);
}
void loop() {
uint32_t jetzt = millis();
static uint32_t vorhin;
const uint32_t intervall = 1000;
if (jetzt - vorhin >= intervall) {
vorhin = jetzt;
for (uint8_t j = 0; j < ANZAHL_TEMP; j++) {
tx.temp[j] = random(150, 550);
}
tx.pir1 = random(0, 2);
tx.pir2 = random(0, 2);
tx.reed1 = random(0, 2);
tx.reed2 = random(0, 2);
tx.reed3 = random(0, 2);
tx.reed4 = random(0, 2);
}
}
// ESP32
#include <Arduino.h>
#include <Wire.h>
const uint8_t I2C_Mega2560 = 0x08;
const uint8_t ANZAHL_TEMP = 6;
//const uint8_t ANZAHL_PIR = 2;
//const uint8_t ANZAHL_REED = 4;
const uint8_t BYTEZAHL = 2 * ANZAHL_TEMP + 1;
union {
uint8_t bytes[BYTEZAHL];
struct {
uint16_t temp[ANZAHL_TEMP];
struct
{
bool pir1: 1 ; // 1 Bit pro bool
bool pir2: 1 ; // 1 Bit pro bool
bool reed1: 1 ; // 1 Bit pro bool
bool reed2: 1 ; // 1 Bit pro bool
bool reed3: 1 ; // 1 Bit pro bool
bool reed4: 1 ; // 1 Bit pro bool
};
};
} rx;
void setup()
{
delay(500);
Wire.begin();
Serial.begin(115200);
Serial.println("\nStart ...");
}
void loop() {
uint32_t jetzt = millis();
static uint32_t vorhin;
const uint32_t intervall = 1000;
if (jetzt - vorhin >= intervall) {
vorhin = jetzt;
Wire.requestFrom(I2C_Mega2560, BYTEZAHL);
int index = 0;
while ( Wire.available() ) {
rx.bytes[index] = Wire.read();
if (index < BYTEZAHL) index++;
}
Serial.printf("empfangene Bytes: %d\n", index);
for (uint8_t j = 0; j < ANZAHL_TEMP; j++)
{
Serial.printf("Temperatur %u: %4.1f°C\n", j, rx.temp[j] / 10.0);
}
Serial.printf(" PIR 1: %u\n", rx.pir1);
Serial.printf(" PIR 2: %u\n", rx.pir2);
Serial.printf(" Reed 1: %s\n", rx.reed1 ? "Ein" : "Aus");
Serial.printf(" Reed 2: %s\n", rx.reed2 ? "Ein" : "Aus");
Serial.printf(" Reed 3: %s\n", rx.reed3 ? "Ein" : "Aus");
Serial.printf(" Reed 4: %s\n", rx.reed4 ? "Ein" : "Aus");
Serial.println("--------------------");
}
}
13 anstelle 18 Bytes ![]()
Gerne möchte ich mehrere Pirs und Reeds zu einem Feld zusammenfassen:
union {
uint8_t bytes[BYTEZAHL];
struct {
uint16_t temp[ANZAHL_TEMP];
struct
{
bool pir[2]: 2 ; // 1 Bit pro bool
bool reed[4]: 4 ; // 1 Bit pro bool
};
};
} tx;
function definition does not declare parameters
bool reed[4]: 4 ; // 1 Bit pro bool
^
Was tue ich da und wo steht, wie es geht? Der Terminus Technikus fehlt mir ![]()
Typspiel, im Sinne von Wortspiel
(aber auch gerne stampfen)
evtl. ein besserer Suchbegriff: "gcc type punning"
Wenn die Bitanzahl größer werden soll, dann könnte man auch direkt über ein Bitarray nachdenken.
Gruß Tommy
Ach komm, da fehlt noch ein Array Access Interface und die Chance drüberweg iterieren zu können.
![]()
Das war damals ein Schnellschuss, weil die Bitmacros bei 32 Bit aufhören.
Das Iterieren könnte man ja mit einer Schleife über den Index machen.
Was meinst Du mit Array Access Interface?
Gruß Tommy
z.B. bitfeld[41] = true;