SimonK/Mikrocopter Brushlessregler I2C Protokoll

OP #3904435
Lesenswert?

Hallo,

ich habe hier gerade einen selbstgebauten AfroESC-Klon liegen. Die 
Ansteuerung über Servosignal geht auch so weit. Ich wöllte das gerne 
aber auch noch über I2C probieren. Wie ist das Protokoll dafür? Ich 
sende die Adresse, das Write-Bit, das ganze wird Geackt, dann sende ich 
einfach die Daten für die Geschwindigkeit, in dem Fall 0x55, das ganze 
wird auch Geackt. Aber der Motor dreht sich nicht.
Ich habe schon mehrere Kombis von mehreren gesendeten Bytes probiert, 
z.B. 0x00 0x55 oder 0x55 0x01 oder ...

Hat hier schon mal jemand so etwas gemacht?
#3904489
Lesenswert?

Peter K. schrieb:
> Hallo,
>
> ich habe hier gerade einen selbstgebauten AfroESC-Klon liegen. Die
> Ansteuerung über Servosignal geht auch so weit. Ich wöllte das gerne
> aber auch noch über I2C probieren. Wie ist das Protokoll dafür? Ich
> sende die Adresse, das Write-Bit, das ganze wird Geackt, dann sende ich
> einfach die Daten für die Geschwindigkeit, in dem Fall 0x55, das ganze
> wird auch Geackt. Aber der Motor dreht sich nicht.
> Ich habe schon mehrere Kombis von mehreren gesendeten Bytes probiert,
> z.B. 0x00 0x55 oder 0x55 0x01 oder ...
>
> Hat hier schon mal jemand so etwas gemacht?

Du kannst Dir den Sourcecode dafür hier mal ansehen:
http://svn.mikrokopter.de/websvn/filedetails.php?repname=Projects&path=%2FTransportables_Koptertool%2Ftags%2FV3.x%2FPKT355_FC086.zip

motortest.c
twimaster.*

I2C-Mode ist der relevante Anteil in motortest.c.

Gehört zu dem PKT-Projekt, deshalb musst Du die PKT spezifischen Teile 
rausschmeissen oder anpassen, Displayausgabe,Uart etc.


Die "Gas"-Werte müssen zyklisch gesendet werden, sonst bleibt der Motor 
stehen.

Christian
OP #3904495
Lesenswert?

Hier noch mal mein Code. Das ist doch eigentlich der selbe?
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif
4

5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <avr/interrupt.h>
8

9
#include "uart.h"
10
#include "i2cmaster.h"
11

12
#define UART_BAUD_RATE 38400
13

14
int main(void){
15
  int ret;
16

17
  DDRD = 0xFF;
18

19
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
20

21
  i2c_init();
22

23
  sei();
24

25
  uart_putc(0xFF);
26

27
  while(1){
28
    ret = i2c_start(0x50 + (1 << 1) + I2C_WRITE);
29
    if(ret){
30
      i2c_stop();
31
    }else{
32
      i2c_write(200);
33
      //i2c_write(0);
34
      i2c_stop();
35
    }
36

37
    _delay_ms(50);
38
  }
39
  return 0;
40
}
#8064990
Lesenswert?

From Ralf Ramsauer's blog (https://blog.vmexit.de/?p=461):

This is a short overview of the I2C protocol of the Oktokopter XL V3: We made a capture of the communication FlightCtrl <> BL-Ctrl.

1
Speed: max. 200kHz
2
Addresses: 0x52-0x62
3
Write: Either one Byte (0-255) or two Bytes (0-2048) denote the speed of the motor
4
Read: On read, a controller returns six Byte:
5
    1: Current in 100mA steps
6
    2: Status (see table below)
7
    3: Temperature in degrees Celsius
8
    4: Raw RPM value (some correction factor needed??) (only BL-Ctrl v3)
9
    5: Unused / Reserved / Voltage for BL_CTRL V3 (see details on Mikrokopter wiki) (only BL-Ctrl v3)
10
    6: Voltage in 100mV steps (only BL-Ctrl v3)

Possible status values that we observed:

1
255: running
2
248: not running but ready

There are more possible status values but we did not observe them yet.

After Digging a bit deeper, we found out, that it is not possible to directly jump from 0 RPM to maximum RPM. Speed has to increase ‘slowly’ in smaller steps. Furthermore, the motor settings must consequently be transmitted, even if they do not change. If a controller doesn’t receive I2C signals any longer, it automatically stops motors after ~500ms.

My own observations:

Some useful links: https://wiki.mikrokopter.de/BL-Ctrl_Fehlerbeseitigung#Fehlercodes_Firmware_.3E.3D_0.35 https://wiki.mikrokopter.de/BL-Ctrl_2.0 https://wiki.mikrokopter.de/BlCtrlProtocol

The Mikrokopter wiki says that the addresses would be 0x50 (write RPM value to motor controller 1), 0x51 (read motor controller 1 status), 0x52 (write RPM value to motor controller 2), 0x53 (read motor controller 2 status), etc.. However, as Ralf also stated, it seems, that the addresses are in fact shifted: 0x52 (write motor 1), 0x53 (read motor 1), and so on.

If you only want to read motor controller status information, you still must continuously send an RPM value (can also be 0). Above it was claimed that before you can start the motor, you need to send RPM 0 once. Could not confirm this, for the BL-Ctrl 2.0 that does not seem to be necessary.

When using the Arduino wire library to talk to the motor controllers (with the Arduino being the I2C master), one needs to take into account how the wire library handles I2C addresses. This example clarifies that:

Example: Actual target addresses 0x54 (0b 0101 0100) [writing to controller 2] and 0x55 (0b 0101 0101) [reading from controller 2] -> The Arduino wire lib takes only the first seven bits (0b 0101 010_ -> which is 0x2A) and by itself appends a 0 for writing and a 1 for reading. So, this is how you write RPM values and request data from a Mikrokopter BL-Ctrl:

// Send RPM value of 37 (out of 255). Note: there is also the possibility to send another byte for higher accuracy, but only its 3 lowest bits are used. Wire.beginTransmission(0x2A); Wire.write(37); Wire.endTransmission();

// Read 3 bytes (for BL-Ctrl 2.0) from the controller. Wire.requestFrom(0x2A, 3, 1);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren