Ja, das klingt sehr plausibel - danke!
uxomm:
Ich muss gestehen, dass ich nicht auf den "Branch" geachtet habe, als ich die Library heruntergeladen habe.
Um ehrlich zu sein, wusste ich bis vor ein paar Minuten gar nicht, was das überhaupt bedeutet.Ich bin einfach auf die Website gegangen, habe auf "Code" und dann auf "Download ZIP" geklickt, und habe das Heruntergeladene dann in meine Arduino-IDE eingebunden.
Dass der Ordnername "TinyWire-rollback" und nicht (wie sonst üblich) "TinyWire-master" lautet, ist mir zwar aufgefallen, ich habe dem aber keine besondere Bedeutung beigemessen - es hat ja alles funktioniert.Ich habe also offensichtlich den "Rollback-Branch" verwendet. Weil das anscheinend der "Default-Branch" ist (siehe Bild). Ich habe keinen Branch aktiv ausgewählt und so habe ich den Default-Branch heruntergeladen.
Somit erklärt sich auch, warum es bei mir funktioniert hat.
Wieder was gelernt - weiß aber noch nicht genau, was
(nämlich wieso Default auf "rollback" steht und nicht auf "master" und was das genau bedeutet).
Danke jedenfalls für die Nachfrage!
Ok, dann macht alles wieder Sinn ![]()
Da der master-Branch anscheinend Fehler hat, hat der Autor wohl einige Änderungen zurück genommen (rollback) und diesen Stand als Default ausgewählt.
Gruß Tommy
Exakt so ist es und so wie es aussieht, wird da momentan auch nicht mehr wirklich dran gearbeitet, weil der letzte Commit in den Master-Branch in 2018 war.
Evtl. wollte er eine Erweiterung vornehmen, deren Realisierung sich als ungeeignet/unmöglich erwiesen hat. Er hat ja einen lauffähigen Defaultstand eingecheckt.
Gruß Tommy
Tommy56:
Evtl. wollte er eine Erweiterung vornehmen, deren Realisierung sich als ungeeignet/unmöglich erwiesen hat. Er hat ja einen lauffähigen Defaultstand eingecheckt.Gruß Tommy
So wie ich es aus den Issues rausgelesen hab, hat er selber nicht mehr die Zeit dazu die Bibliothek weiterzuentwickeln. Der Defaultstand passt ja soweit auch, das Problem, was ich jetzt nur hab ist, dass ich nicht mehrere Bytes senden/empfangen kann. Siehe Surprise, as of f0eb04f the communication doesn't work anymore, only 255 response · Issue #44 · rambo/TinyWire · GitHub
Scheinbar soll das mit der Rollback-Version auch wieder funktionieren, aber bei mir kommt nach wie vor bei mehreren Bytes 255 für jedes Byte zurück. Deshalb mach ich es jetzt einfach so, dass der RaspberryPi (Master) die gewünschte Anzahl Impulse berechnet und einfach nur diesen Wert an den ATtiny überträgt. Somit komm ich auch mit einem Byte klar.
somann88:
... das Problem, was ich jetzt nur hab ist, dass ich nicht mehrere Bytes senden/empfangen kann.
Vor ein paar Jahren habe ich das mal gemacht, da könnte ich bei Interesse suchen. Aber wenn es auch mit einem Byte geht, dann ist es ja gut.
@agmue: Habe gerade eben noch deine Antwort gelesen... wäre super, wenn du mir deinen Code raussuchen könntest, oder mal über meinen drüber schaust, ob ich das so richtig gemacht hab. Danke!
Jetzt hab ich doch ein Problem...
Die Impulse sind größer als 255, das heißt, mir reicht ein Byte doch nicht aus.
Also muss ich jetzt doch mehrere Bytes senden. Kann mir mal bitte jemand sagen, ob mein Code grundsätzlich so korrekt ist?
ATtiny85 (Slave)
#include <TinyWireS.h> // Bezieht I2c Bibliothek ein
#define I2C_SLAVE_ADDRESS 0x20 // I2c Slave Adresse
volatile uint8_t i2c_regs[] =
{
0x10,
0x20,
0x30,
0x40,
};
const byte reg_size = sizeof(i2c_regs);
void setup() {
TinyWireS.onRequest(requestEvent); // Bei I2c Anfrage springt in requestEvent Funktion
TinyWireS.onReceive(receiveEvent);
TinyWireS.begin(I2C_SLAVE_ADDRESS); // Verbindet mit I2c Bus
}
void loop() {
TinyWireS_stop_check();
}
void receiveEvent(uint8_t value) {
// TBD
}
void requestEvent() {
for (uint8_t i = 0; i < reg_size; i++) {
TinyWireS.send(i2c_regs[i]);
}
}
RaspberryPi (Master)
# Python
from smbus2 import SMBus
with SMBus(1) as bus:
# Read a block of 4 bytes from address 0x20, offset 0
block = bus.read_i2c_block_data(0x20, 0, 4)
# Returned value is a list of 4 bytes
print(block)
Das Ergebnis vom RaspberryPi ist dann:
[255, 255, 255, 255]
somann88:
@agmue: Habe gerade eben noch deine Antwort gelesen... wäre super, wenn du mir deinen Code raussuchen könntest, oder mal über meinen drüber schaust, ob ich das so richtig gemacht hab. Danke!
Der Slave-Entwurf für Wire stammt von Serenifly, ich hab es dann für TinyWireS adaptiert, wenn ich mich richtig erinnere.
Es gibt ein paar Warnungen, da müßte man nochmal genauer schauen, letztlich funktioniert es aber.
Einen RasPi habe ich nicht, daher ein Mega2560 wegen der eingebauten PullUp-Widerstände als Master:
#include <Wire.h>
const int SLAVE_ADR = 2;
// http://forum.arduino.cc/index.php?topic=42158.0 how to convert long int to byte*
uint32_t wert;
byte buf[4];
byte zAlt = 0;
byte zNeu = 0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
setIndex(SLAVE_ADR, 0);
zNeu = readByte(SLAVE_ADR);
if (zNeu != zAlt) {
Serial.println(F("alle Bytes sequentiell von Index 0 lesen"));
Serial.print(zNeu, HEX);
buf[0] = zNeu;
Serial.print(F(" "));
buf[1] = readByte(SLAVE_ADR);
Serial.print(buf[1], HEX);
Serial.print(F(" "));
buf[2] = readByte(SLAVE_ADR);
Serial.print(buf[2], HEX);
Serial.print(F(" "));
buf[3] = readByte(SLAVE_ADR);
Serial.print(buf[3], HEX);
Serial.print(F("\t"));
wert = buf[0] + (buf[1] << 8) + ((1L * buf[2]) << 16) + ((1L * buf[3]) << 24);
Serial.println(wert, HEX);
Serial.println(F("-----"));
zAlt = zNeu;
}
}
//ein Byte anfordern und lesen
int readByte(int adr)
{
Wire.requestFrom(adr, 1);
return Wire.read();
}
//Index an Slave senden
void setIndex(int adr, byte index)
{
Wire.beginTransmission(adr);
Wire.write(index);
Wire.endTransmission();
}
ATtiny85 als Slave:
// ATMEL ATtiny45/85
//
// +-\/-+
// Reset 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 SCL
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0 SDA
// +----+
// http://forum.arduino.cc/index.php?topic=296483.0
/* I2C */
// Get this from https://github.com/rambo/TinyWire
#include <TinyWireS.h>
#define SLAVE_ADR 0x02
#define NUMBER_OF_REGISTERS 4
byte registers[NUMBER_OF_REGISTERS]; //Array für Daten
int index;
uint32_t wert = 0x12345678;
void setup()
{
TinyWireS.onRequest(requestEvent);
TinyWireS.onReceive(receiveEvent);
TinyWireS.begin(SLAVE_ADR);
}
void loop()
{
registers[0] = wert;
registers[1] = wert >> 8;
registers[2] = wert >> 16;
registers[3] = wert >> 24;
delay(1000);
wert++;
}
void requestEvent()
{
TinyWireS.send(registers[index]); //aktuellen Index auf Bus schreiben
index = (index + 1) % NUMBER_OF_REGISTERS; //Index inkrementieren
}
void receiveEvent(uint8_t numBytes)
{
int index = TinyWireS.receive(); //Index lesen
if (index < NUMBER_OF_REGISTERS) //setzen wenn im Array
::index = index;
else
::index = 0; //wenn außerhalb auf 0 setzen
}
Probiere jetzt bitte erstmal selbst, ich lasse meinen Testaufbau aber noch etwas stehen.
agmue:
Der Slave-Entwurf für Wire stammt von Serenifly, ich hab es dann für TinyWireS adaptiert, wenn ich mich richtig erinnere.Es gibt ein paar Warnungen, da müßte man nochmal genauer schauen, letztlich funktioniert es aber.
Einen RasPi habe ich nicht, daher ein Mega2560 wegen der eingebauten PullUp-Widerstände als Master:
#include <Wire.h>
const int SLAVE_ADR = 2;
// how to convert long int to byte* - Syntax & Programs - Arduino Forum how to convert long int to byte*
uint32_t wert;
byte buf[4];
byte zAlt = 0;
byte zNeu = 0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}
void loop()
{
setIndex(SLAVE_ADR, 0);
zNeu = readByte(SLAVE_ADR);
if (zNeu != zAlt) {
Serial.println(F("alle Bytes sequentiell von Index 0 lesen"));
Serial.print(zNeu, HEX);
buf[0] = zNeu;
Serial.print(F(" "));
buf[1] = readByte(SLAVE_ADR);
Serial.print(buf[1], HEX);
Serial.print(F(" "));
buf[2] = readByte(SLAVE_ADR);
Serial.print(buf[2], HEX);
Serial.print(F(" "));
buf[3] = readByte(SLAVE_ADR);
Serial.print(buf[3], HEX);
Serial.print(F("\t"));
wert = buf[0] + (buf[1] << 8) + ((1L * buf[2]) << 16) + ((1L * buf[3]) << 24);
Serial.println(wert, HEX);
Serial.println(F("-----"));
zAlt = zNeu;
}
}
//ein Byte anfordern und lesen
int readByte(int adr)
{
Wire.requestFrom(adr, 1);
return Wire.read();
}
//Index an Slave senden
void setIndex(int adr, byte index)
{
Wire.beginTransmission(adr);
Wire.write(index);
Wire.endTransmission();
}
ATtiny85 als Slave:// ATMEL ATtiny45/85
//
// +-/-+
// Reset 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 SCL
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0 SDA
// +----+
// Anfänger - I2C- Senden von mehreren Analogwerten als String vom Slave zum Master - Deutsch - Arduino Forum
/* I2C */
// Get this from GitHub - rambo/TinyWire: My modifications to TinyWire Arduino libs
#include <TinyWireS.h>
#define SLAVE_ADR 0x02
#define NUMBER_OF_REGISTERS 4
byte registers[NUMBER_OF_REGISTERS]; //Array für Daten
int index;
uint32_t wert = 0x12345678;
void setup()
{
TinyWireS.onRequest(requestEvent);
TinyWireS.onReceive(receiveEvent);
TinyWireS.begin(SLAVE_ADR);
}
void loop()
{
registers[0] = wert;
registers[1] = wert >> 8;
registers[2] = wert >> 16;
registers[3] = wert >> 24;
delay(1000);
wert++;
}
void requestEvent()
{
TinyWireS.send(registers[index]); //aktuellen Index auf Bus schreiben
index = (index + 1) % NUMBER_OF_REGISTERS; //Index inkrementieren
}
void receiveEvent(uint8_t numBytes)
{
int index = TinyWireS.receive(); //Index lesen
if (index < NUMBER_OF_REGISTERS) //setzen wenn im Array
::index = index;
else
::index = 0; //wenn außerhalb auf 0 setzen
}
Probiere jetzt bitte erstmal selbst, ich lasse meinen Testaufbau aber noch etwas stehen.
Super, danke dir agmue!
Ich konnte mir jetzt einen funktionierenden Code schreiben. Ich lese aber die Bytes Stück für Stück einzeln aus. Die Block-Read Funktion gibt mir nach wie vor nur 255 zurück.
Eine grundsätzliche Frage hab ich aber noch. Was genau bedeutet denn der Offset bei einer "i2c block read" Funktion? Unabhängig von der verwendeten Platform, ist es ja immer der selbe Parameter-Aufbau: Adresse, Offset, Anzahl Bytes.
Siehe: smbus2 · PyPI (Example 2: Read a block of data)
Wenn ich die Funktion jetzt so aufrufe...
block = bus.read_i2c_block_data(0x20, 0, 4)
...würde Offset 0 doch bedeuten, dass die Funktion beim ersten Byte anfängt zu lesen und dann müsste dieser Teil doch alle vier Bytes zurück geben:
void requestEvent() {
for (uint8_t i = 0; i < reg_size; i++) {
TinyWireS.send(i2c_regs[i]);
}
}
Ups, in meiner usiTwiSlave.c habe ich noch diese von mir geänderte Stelle gefunden:
/* if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) ) http://www.mikrocontroller.net/topic/38917 Datum: 06.11.2014 18:47 */
if ( !( PIN_USI & ( 1 << PIN_USI_SCL ) ) )
somann88:
Ich lese aber die Bytes Stück für Stück einzeln aus. Die Block-Read Funktion gibt mir nach wie vor nur 255 zurück.
Bitte schau mal in TinyWireS.h, da steht nichts von mehreren Bytes:
TinyWireS.send(uint8_t data){ // sends a requested byte to master
Bei Wire ginge auch ein Block (I2C - Arduino als Slave):
Wire.write(reg[index].b, sizeof(RegisterData));
Du könntest also einen ATmega328 auf einem ProMini oder solo in Erwägung ziehen.
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.