Seite 1 von 1

Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 12:03 ,Sa 6. Jul 2019,
von DerMarkus
Ausgehend von einigen Beiträgen im Netz nutze ich die USB-Schnittstelle des IMAX B6 und schreibe die Daten in eine Datenbank. So kann ich mir live oder später die Ladevorgänge anschauen:
Ladekurve.jpg
Außerdem lasse ich mir eine Mail schicken, wenn der Akku voll ist.

Wenn jemand Interesse hat, kann ich weitere Infos zur genutzten Hardware / Software posten.

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 01:02 ,So 7. Jul 2019,
von DeWe
An das Ganze habe ich mit meinen Hyperion Ladegeräten auch damals mal angedacht, zumal die Funktion ja auch gegeben war.... Habe es aber aus Bequemlichkeit sein lassen, da die Lader zu weit vom PC weg stehen.
Interessant wäre dann :
Ladegeräte (2x) via WLAN im Netz und auf der Synology automatisch speichern. Sprich die Elektronik muss pro Charger (welche auch noch jeweils 2 Lipos getrennt oder ein 7-12S Lipo laden können) eigene IDs mitbringen....

Wie unterscheidest du unterschiedliche Lipos? (z. B. Wenn du 3x 5000 6S hättest?)

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 01:24 ,So 7. Jul 2019,
von doelle4
Finde das Toll was du da machst :good: . Bitte um nähere Infos
Gruß Hans

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 07:31 ,So 7. Jul 2019,
von faboaic
Cool.
Wollte ich auch schon mal machen mit esp8266 über WLAN
Leider nie wirklich Zeit und Lust gehabt, das umzusetzen.

Würde wohl die Werte jeweils über mqtt in die influxdb rein schreiben und über grafana visualisieren.
Benachrichtigung, etc dann über node red.

Mehr Infos zu deiner Umsetzung wären schön. :)

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 09:48 ,So 7. Jul 2019,
von DerMarkus
Die Hardware besteht aus folgenden Komponenten:
- Arduino-Board
- USB-Shield
- ESP8266 ESP-01
- USB-Kabel

Über das USB-Kabel wird das System vom Ladegerät mit Spannung versorgt.

Der Aufbau sieht so aus:
Img_1307.jpg
Img_1309.jpg
Img_1308.jpg

Hier der Code für den ESP:

Code: Alles auswählen

//***********************************************************************
//***  Programm-Version  ************************************************
//***********************************************************************

#define PrgVer 1.00                 // Datum: 2018-05-09
#define PrgVer 1.01                 // Datum: 2018-05-09
                                    // Nur ein Byte als Kommando
#define PrgVer 1.02                 // Datum: 2018-09-15
                                    // Ausgabe MAC-Adresse
#define PrgVer 1.03                 // Datum: 2019-02-03
                                    // Einbau Aufruf "WIFIconnect"
                                    // mit Reconnect
                                    
//***********************************************************************
//***  Includes  ********************************************************
//***********************************************************************

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

//***********************************************************************
//***  Deklaration  *****************************************************
//***********************************************************************

boolean DgbOn = false;

const char* ssid = "MySSID";
const char* password = "MyPASSWORD";

ESP8266WebServer server(80);

String WebString = "";

char ChrDummy[] = "FF";
int IntDummy;

//***********************************************************************
//*** setup  ************************************************************
//***********************************************************************

void setup()
{
  Serial.begin(9600);
  if (DgbOn) Serial.println("");
  if (DgbOn) Serial.println(PrgVer);
  if (DgbOn) Serial.println("Programm <ESP8266_IMAXB6V2> gestartet...");
  if (DgbOn) Serial.println("");
  if (DgbOn) Serial.print("MAC: ");
  if (DgbOn) Serial.println(WiFi.macAddress());

  WIFIconnect();

  if (DgbOn) Serial.print("Arduino-IP = ");
  if (DgbOn) Serial.println(WiFi.localIP());
  if (DgbOn) Serial.println("");

  server.on("/", []()
  {
    server.send(200, "text/plain", "ESP8266_IMAXB6V2, PrgVer = " + String(PrgVer) + "\n" +
                                   "URL: http://" + WiFi.localIP().toString() + "/send?cmd=5A" + "\n" +
                                   "URL: http://" + WiFi.localIP().toString() + "/rssi");
  });

  server.on("/rssi", []()
  {
    server.send(200, "text/plain", String(WiFi.RSSI()) + "dBm");
  });
  
  server.on("/send", []()
  {
    String ServerArg = server.arg("cmd");

    // Server-Argument zerlegen und als Integer ausgeben...
    do
    {
      ServerArg.substring(0, 2).toCharArray(ChrDummy, 3);       // erste zwei Zeichen in Char-Array wandeln
      IntDummy = hex2int(ChrDummy, 2);                          // Char-Array in Integer wandeln
      Serial.write(IntDummy);
      ServerArg = ServerArg.substring(3, ServerArg.length());   // String ab drittem Zeichen kopieren
    } while (ServerArg.length() > 1);

    delay(1000);

    server.send(200, "text/plain", Serial.readString());
  });

  server.begin();
  if (DgbOn) Serial.println("HTTP server started");
  if (DgbOn) Serial.println("");
}

//***********************************************************************
//*** loop  *************************************************************
//***********************************************************************

void loop(void)
{
  server.handleClient();
  
  delay(100);
  
  if (WiFi.status() != WL_CONNECTED)
  {
    WIFIconnect();
    delay(200);
  }
}

//***********************************************************************
//***  WIFIconnect  *****************************************************
//***********************************************************************

void WIFIconnect()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
   
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    if (DgbOn) Serial.print(".");
  }
  if (DgbOn) Serial.println();
  
  server.begin();
}

//***********************************************************************
//***  hex2int  *********************************************************
//***********************************************************************

int hex2int(char *a, unsigned int len)
{
  int val = 0;

  for (int i=0; i < len; i++)
    if(a[i] <= 57)
      val += (a[i]-48)*(1<<(4*(len-1-i)));
    else
      val += (a[i]-55)*(1<<(4*(len-1-i)));

  return val;
}

//***********************************************************************
//***  int2hex  *********************************************************
//***********************************************************************

String int2hex(int wert, int stellen)
{
  String temp = String(wert, HEX);
  String prae = "";
  int len = temp.length();
  int diff = stellen - len;
  for (int i = 0; i < diff; i++) prae = prae + "0";
    
  return prae + temp;
}

//***********************************************************************
//***  Ende  ************************************************************
//***********************************************************************

Hier der Code für den Arduino:

Code: Alles auswählen

//***********************************************************************
//***  Programm-Version  ************************************************
//***********************************************************************

#define PrgVer 1.00                 // Datum: 2018-05-09

//***********************************************************************
//***  Includes  ********************************************************
//***********************************************************************

#include <Max3421e.h>
#include <Usb.h>
#include <SoftwareSerial.h>

//***********************************************************************
//***  Deklaration  *****************************************************
//***********************************************************************

#define RX 2  // = TX-Pin am ESP-01
#define TX 3  // = RX-Pin am ESP-01

SoftwareSerial softSerial(RX, TX);

#define MIRROR_ADDR        1
#define MIRROR_EP          1
#define MIRROR_IF          0
#define EP_MAXPKTSIZE   0x40
#define EP_POLL         0x0A

EP_RECORD ep_record[2];

char msg[10] = {0x0F, 0x03, 'x', 0x00, 'x', 0xFF, 0xFF}; // 'x' durch Kommando ersetzen!
char buf[EP_MAXPKTSIZE] = {0};

byte b;
String Separator = "";
String Answer = "";
    
MAX3421E Max;
USB Usb;

//***********************************************************************
//*** setup  ************************************************************
//***********************************************************************

void setup()
{
  Serial.begin(9600);
  Serial.println("");
  Serial.println(PrgVer);
  Serial.println("Programm <IMAXB6V2_ESP8266_USB> gestartet...");
  Serial.println("");
  
  Max.powerOn();
  delay(200);

  softSerial.begin(9600);
}

//***********************************************************************
//*** loop  *************************************************************
//***********************************************************************

void loop() 
{
  Max.Task();
  Usb.Task();

  if (Usb.getUsbTaskState() == USB_STATE_CONFIGURING) //wait for addressing state
  {  
    IMAX_init();
    Usb.setUsbTaskState(USB_STATE_RUNNING);
  }

  if (softSerial.available())
  {
    b = softSerial.read();

    Serial.print("Sende Kommando <");
    Serial.print((byte) b, HEX);
    Serial.println("> an IMAXB6V2...");

    msg[2] = b;       // 'x' auf Byte 2 ersetzen
    msg[4] = b;       // 'x' auf Byte 3 ersetzen
    
    if (Usb.getUsbTaskState() == USB_STATE_RUNNING)
    { 
      IMAX_poll();
    }
  }
}

//***********************************************************************
//*** IMAX_init  ********************************************************
//***********************************************************************

void IMAX_init(void)
{
  byte rcode = 0;

  ep_record[0] = *( Usb.getDevTableEntry( 0,0 ));
  ep_record[1].MaxPktSize = EP_MAXPKTSIZE;
  ep_record[1].Interval   = EP_POLL;
  ep_record[1].sndToggle  = bmSNDTOG0;
  ep_record[1].rcvToggle  = bmRCVTOG0;
    
  Usb.setDevTableEntry(1, ep_record);
    
  rcode = Usb.setConf(MIRROR_ADDR, 0, 1);                    
  if (rcode)
  {
    Serial.print("Error in Usb.setConf, return code = ");
    Serial.println(rcode);
    while(1);
  }
  
  rcode = Usb.setProto(MIRROR_ADDR, 0, 0, 0);
  if (rcode)
  {
    Serial.print("Error in Usb.setProto, return code = ");
    Serial.println(rcode);
    while(1);
  }
  
  Serial.println("IMAXB6V2 initialized...");
}

//***********************************************************************
//*** IMAX_poll  ********************************************************
//***********************************************************************

void IMAX_poll(void)
{
  char i;
  byte rcode = 0;

  rcode = Usb.outTransfer( MIRROR_ADDR, MIRROR_EP, 0x08, msg);
  if (rcode != 0)
  {
    Serial.print("Error in Usb.outTransfer, return code = ");
    Serial.println(rcode);
    while(1);
  }
    
  delay(1000);
  
  rcode = Usb.inTransfer( MIRROR_ADDR, MIRROR_EP, EP_MAXPKTSIZE, buf);
  if (rcode != 0)
  {
    Serial.print("Error in Usb.inTransfer, return code = ");
    Serial.println(rcode);
    while(1);
  }

  // Puffer in String umbauen, da eine binäre 0 (0x00)
  // mit "softSerial.write" nicht gesendet werden kann
  if (buf[0] > 0)
  {
    Separator = "";
    Answer = "";
    
    for (i=0; i < 41; i++)
    {
      Answer = Answer + Separator + int2hex((byte) buf[i],2);
      Separator = "-";
    }

    buf[0] = 0;
  }

  softSerial.print(Answer);

  Serial.print("str = ");
  Serial.print(Answer);

  Serial.println();

  delay(1000);
}

//***********************************************************************
//***  int2hex  *********************************************************
//***********************************************************************

String int2hex(int wert, int stellen)
{
  String temp = String(wert, HEX);
  String prae = "";
  int len = temp.length();
  int diff = stellen - len;
  for (int i = 0; i < diff; i++) prae = prae + "0";
    
  return prae + temp;
}

//***********************************************************************
//***  Ende  ************************************************************
//***********************************************************************

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 10:04 ,So 7. Jul 2019,
von DerMarkus
Wie unterscheidest du unterschiedliche Lipos? (z. B. Wenn du 3x 5000 6S hättest?)

Diese Frage bzw. dieses „Problem“ stellt sich mir nicht. Ich lese einfach die einzelnen Spannungen (maximal 6) aus. Bei einem 3S sind die restlichen 3 Spannungs-Werte etwa 0 Volt. Bei einem 4S sind die restlichen 2 Spannungs-Werte etwa 0V.

Wenn ich mehrere Ladegeräte hätte, dann würde jedes eine eigene IP-Adresse bekommen.

Per Browser kann ich über WLAN auf das Ding zugreifen und bekomme dann diese Anzeige:
Browser.jpg

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 15:51 ,So 7. Jul 2019,
von DeWe
Ich habe mich etwas falsch ausgedrückt :
Ich habe Duo charger : Sprich es können bis zu 2 6S Lipos einzeln zur gleichen Zeit an einem Ladegerät geladen werden oder ein 7S - 12S an beiden Ausgängen.

Somit können bei meine 2 Ladegeräten 4 Lipos bis 6S zur gleichen Zeit behandelt werden.

Meines Erachtens macht es Sinn, die Ladekurven dem jeweiligen Lipo zuzuordnen, damit man eine Historie pro Lipo bekommt. Daher die Frage der Unterscheidung. Im Regelfall hat man ja mehrere Lipos von einem Typ zu Hause. Wenn ich 3 x3S 3000 und 4x 3S 2200mAh und 2x 3S 1800mAh besitze kann ich nicht wissen, welche Ladekurven zu welchen Lipos in der Vergangenheit gehören... Ich hoffe es ist diesmal ein wenig verständlicher ;)

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 16:18 ,So 7. Jul 2019,
von DerMarkus
Ok, jetzt verstehe ich es. Mit meinem Ladegerät (SKYRC IMAX B6 V2) kann ich nur einen Akku laden. :(

PS: Die Daten, die ich vom Ladegerät im 2min-Takt abfrage, schreibe ich per Python-Script in eine MySQL-Datenbank auf meiner Synology-NAS. Die Software amCharts (www.amcharts.com) erstellt die Grafik im Browser-Fenster.

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 23:06 ,So 7. Jul 2019,
von DeWe
Wenn der Urlaub vorbei ist und ich Abends Langeweile habe, schaue ich mal über den Code.....
Hat jemand etwas gegen ein Touchscreen Display am Arduino? Wenn, welches sollen wir nehmen... muss ja nicht groß sein, Hauptsache man kann Lipos Selectieren, Neue anlegen, evtl Settings anpassen... Soweit nur eine Idee aus dem Wasserglas ;)

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 21:30 ,Do 3. Okt 2019,
von DerMarkus
Hier noch eine Skizze zum Anschluss:
Arduino+ESP01.jpg
Quelle:

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 09:34 ,Mo 7. Okt 2019,
von realorlando
Danke für die Bilder und die Infos. Ein sehr interessantes Projekt wie ich finde.
Aber wie hängst du deinen Akku in die Schaltung rein?? Wie den Temperaturfühler über den Spannungsteiler? Das ist mir noch nicht ganz klar.
Danke schon mal.


EDIT: Moment, jetzt hab ichs kappiert - hab gerade den Quellcode gelesen: Das passiert ja alles per USB.... Sorry für die Fragen ;)

Re: Projektvorstellung: USB Schnittstelle SKYRC IMAX B6 V2

Verfasst: 20:57 ,Mo 7. Okt 2019,
von DerMarkus
Die ersten Fragen haben mich tatsächlich etwas verwirrt 😐

Ich habe von dem verlinkten YouTube-Video nur die Schaltung kopiert. Das Ladegerät selbst ist per USB angeschlossen. An dem USB Host Shield.

Wenn Du willst, schicke ich Dir noch den Python-Code, mit dem ich die Daten zyklisch in meine SQL-Datenbank schreibe. Und den PHP- oder HTML-Code, mit dem ich die Grafik erzeuge.