Forum: Mikrocontroller und Digitale Elektronik SimonK/Mikrocopter Brushlessregler I2C Protokoll


von Peter K. (peterka2000)


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?
von unbekannt (Gast)


Lesenswert?

Such mal im Forum von mikrokopter.de, da gibts Beträge zu dem Thema
von Peter K. (peterka2000)


Lesenswert?

Hab geguckt. Das 
http://wiki.mikrokopter.de/en/BL-Ctrl_V1.2#Controlling_with_own_Hardware 
gefunden. Mein Code ist identisch, der Motor dreht sich aber trotzdem 
nicht. Einzig das Kein-Signal-Erkannt-Piepoen vom SimonK hört auf.
von Christian B. (christian_b28)


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
von Peter K. (peterka2000)


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
}
von Peter K. (peterka2000)


Lesenswert?

Für alle die es wissen wollen: Es geht inzwischen.

Man muss dem Regler ganz am Anfang erstmal 0x00 schicken.
von OneChannelScope (one_channel_scope)


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.

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

Possible status values that we observed:

    255: running
    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);
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.