Upgrade meiner Solo Electra mit LiFePo-Akku, aktuellem Motor und Controller

Ich habe in 2012 meine Solo Electra restauriert. Die Elektrik habe ich damals auf dem Stand gelassen, auf dem sie gebaut wurde bzw. auf dem ich sie erhalten habe.

Dies bedeutet 24 Volt 850 Watt Motor, 2×12 Volt 50Ah Auto Akkus in Serie geschaltet und keine Motorelektronik. Mangels Motorsteuerung muss man also immer entweder Vollgas oder gar kein Gas geben. Es gibt nichts dazwischen. Damit kann man nur ruckhaft fahren, vor allem in der Stadt, wenn man einem langsamen Auto hinterherfährt ist diese Fahrweise schon unangenehm und seltsam.

Für die Akkus ist das auch nicht besonders gesund, so dass ich schon zwei Blei-Batterien mit Plattenschluss entsorgen müsste.

In 2019 soll dieses ganze veraltete Konzept durch ein aktuelles ersetzt werden.

Die Lösung besteht aus folgenden Teilen:

36 Volt 20Ah LiFePo4 Akkumulator.  Dieser Akku besitzt ein integriertes Bateriemanagement, das ihn vor Schäden durch z.B. Überstrom und Tiefentladung schützt. Der Akku gibt 40 Ampere im Dauerbetrieb ab.

Dieser Akku hält 36×20=0,72Kwh Energie. Diese Energiemenge kann weitgehend auch genutzt werden. Die alten Akkus hatten 24*50=1,2Kwh Energie, die aber nur zu ~40% genutzt werden durfte, um die Akkus nicht zu zerstören. Ich erwarte daher, trotz kleinerem Akku, keine Reichweiteneinbussen.

Der LifFePo4 Akku ist im Gegensatz zu seinem LiIon-Bruder nicht explosionsgefährdet, aber deutlich teurer (in etwa doppelter Preis). Für mein Exemplar wären rund 700 Euro fällig gewesen, ich bekomme aber ein ungenutztes Exemplar auf dem Gebrauchtmarkt für 270 Euro.

36 Volt 800 Watt Brushed Elektromotor MY1080. Dieser China-Motor wird in diversen Varianten für E-Scooter von 250..1000 Watt verkauft und hat dort seine Alltagstauglichkeit und Haltbarkeit bewiesen. Außerdem sind seine Abmessungen ganz nahe an denen des Originalmotors. Der Motor kostet rund 80 Euro bei einem deutschen Händler.

MY1080-1

Kelly Controller KDS48100E. Dieser Controller kann bei 36 (24..48) Volt bis zu 60 Ampere Dauerstrom abgeben, in Spitzen bis zu 100 Ampere. Er besitzt Anschlüsse für Hall-Sensor-Gasgriffe, Anzeigegeräte, Notabschalter etc. Er ist außerdem per RS232 konfigurierbar. Der Controller kommt aus China und kostet mit Zubehör rund 110 Dollar.

Berechnung der notwendigen Kettenritzel

Der Motor besitzt ein Ritzel nach der China-Norm T8F. Diese wird in ATVs/Quads verwendet. Man benötigt dazu eine passende Kette und ein zweites Ritzel. Diese Kombination Kette+2 Ritzel ersetzt dann den alten Riemenantrieb der Solo Electra. Dieser Antrieb geht auf die Tretwelle, von dort geht ein zweiter Kettenantrieb mittels Moped-Kette ans Hinterrad. Den zweiten Teil lasse ich unverändert, es wird also nur der Riemenantrieb durch einen Kettenantrieb ersetzt. Die Solo Electra ist ein Mofa, darf also nur 25 km/h fahren. Dies muss auch durch die neuen Ritzel sichergestellt werden.

Nachmessen des alten Antriebs ergibt:

  • Riemenantrieb: Durchmesser des Antriebrads 52mm, Durchmesser des Abtriebrads 183mm. Die Untersetzung ist bei einem Riemenantrieb der Teiler der Durchmesser, hier also 52/183.
  • Kettenantrieb: Antriebsritzel 13 Zähne, Radritzel 50 Zähne. Die Untersetzung ist bei einem Kettenantrieb das Verhältnis der Zähne, hier also 13/50.
  • Die Gesamtuntersetzung ist damit 52*13/(183*50) = 1/13,5.

Ich habe das auch direkt am Fahrzug überprüft, indem ich die Motorwelle 13,5-mal gedreht habe. Dann dreht sich das Hinterrad genau 1 mal.

Anhand des Raddurchmessers (0,415m) kann man berechnen, dass dieses Rad bei 320 U/min fast genau 25 km/h fährt. Man kann rückrechnen, dass dann der alte Motor mit 4315 U/min laufen muss und an der Tretwelle 1231 U/min anliegen.

Diesen Wert, 1231 U/min an der Tretwelle, muss auch der neue Motor maximal erreichen. Das Motorritzel hat 11 Zähne. Damit kann man berechnen, dass das Abtriebsritzel an der Tretwelle 25,02 Zähne haben muss. Ein Ritzel mit 25 Zähnen ist damit ideal.

Leider sind nicht alle Zahnwerte für T8F-Ritzel am Markt einfach verfügbar, in Deutschland gibts maximal 20 Zähne, ich finde aber einen chinesischen Händler der 25 Zahn Ritzel verkauft.

Das Ritzel passt so wie es ist erst einmal nicht auf die Tretwelle, muss also aufgebohrt werden. Außerdem muss die Riemenscheibe durch dieses neue Ritzel ersetzt werden.

Rohlinge der Zahnräder und des Achsaufsatzes.

Der neue Motor eingebaut:

Ausdrehen der Zahnräder

Um die Zahnräder in der Drehmaschine einspannen zu können, habe ich Alurohre gekauft, die etwas geringeres Durchmesser als die Zahräder haben. Diese wurden aufgesägt und um die Zahnräder herumgespannt. Dann lassen sich die Zahnräder gut einspannen. Zentriert wurde mittels Meßuhr auf die vorhandene Bohrung.

Ausdrehen des kleineren Ritzels

Alles fertig gedreht.

Die beiden Zahnräder wurden mit dicken Schweisspunkten auf das Achslager aufgeschweisst.
Hier ist das Achslager schon montiert, die Kette zum Hinterradantrieb bereits wieder aufgelegt. Die Kette vom Motor zum Achslager muss noch passend gekürzt werden.

Das Kettenschloß an der gekürzten Kette
Beide Ketten betriebsbereit.

Elektrik

Computer History Project 2018: Bringing back a Morrow V9054 1.8 GHz spectrum analyzer back to life

After having revived a HP E1498 VXI controller, which is a VXI Slot sized version of a HP9000 UNIX workstation from the late 90ies of the last century (LINK here) and the revival of a military use Subsonic analysis VME mainframe, it was only a question of time and opportunity to start the next computer history project.

The opportunity came in march 2018. Someone at eBay sold several new old stock Spectrum Analyzers.
I always looked for such a tool but was not willing pay 700 Euros or more for it. The eBay offer was roughly 300 Euros including delivery from USofA and customs. The reason for the low price was that the Analyzer came as a VXI slot card. This means no display, no input knobs and switches. A VXI mainframe controls the card and allows to transfer the data to a PC.

For most people, this is not very attractive. But I have a beautiful VXI  mainframe running, no problem to insert the spectrum analyzer card. So I decided to buy it. Some days later the analyzer arrived.

Morrow Technologies V9054 1.8Ghz Spectrum Analyzer

Morrow Technologies is a company that developed complex hardware solution for its customers. At some point in the mid 90s, they decided to develop some measurement devices because they need such tools themselves and to sell them in the VXI market.
They produced several Spectrum Analyzers, most of them are VXI based devices, which was a unique selling point then and as far as I know, is still today. They went out of the Spectrum Analyzer business later but are still
present with their main product line, which are industrial displays. Maybe I am leaving out important things, but this is what I understand from their website and company history.

My device is a Morrow V9054. It can be used in the range 100KHz .. 1.8GHz. It is a C sized VXI card which occupies two slots in the mainframe. Control is completely via VXI Bus. This means all control commands are send via VXI Word Serial Protocol and all responses (e.g. traces) are sent back by the same channel.

Displaying analyzer data in real-time, can this be done?

Displaying trace data with e.g. 25 frames per second requires transferring roughly 25*2K bytes per second from the VXI mainframe to the PC (for 1024 trace points with 16 bit value per point). This is roughly a continuous transfer of 50 KByte/s. Rendering must be able to process 1K data values with a rate of 25 frames per second.

I want to display the data in a web browser and to transfer the data with WebSockets.
So my first evaluation was to check if these requirements can be met with that technology.  I wrote a backend that generates some fake data and runs on the mainframe controller. This backend uses libwebsockets, a C implementation of WebSockets. The frontend was a simple TypeScript browser application that uses a HTML5 Canvas to render the data as pixels like a scope display.

The first test, without rendering, just pure transmission speed test, showed that I can transfer 600KBytes/second between a C written client and server. The VXI mainframe offers only 10MBit LAN access. So the data transfer
will have no problem with the required data transfer rate. The transmission rate would allow more than 200 frames per second.

The second test was to add HTML5 rendering and to use a browser as client. I experimented with several frame rates between 10 and 50 frames per second and found that the browser is not dropping frames up to 40 frames per second. My requirement is 25 fps, so rendering is also no problem.

To summarize, the targeted technologies would allow a nice rendering of the  analyzer data.

The question is then, how fast can the spectrum analyzer deliver its data?

Accessing the Spectrum Analyzer

The Device arrived with one diskette and one CD.
The diskette (20 years old) contained some libraries for Windows 95 and some include files for programmers. The CD contains a Windows 95 application which can access all spectrum analyzers from Morrow.

The libraries for Windows 95 include a PnP driver, a spectrum analyzer library and several transport layer libraries. These libraries include ISA Bus, VISA and TCP/IP. The later supports some Morrow developed protocol for some of their products that allow TCP/IP access. My device does not allow this. It only allows VXI Serial Word Protocol.

The „closest“ library for my environment is the VISA library. It uses SCPI codes to control the  device. My VXI controller supports SCPI so I am able to access the V9054 with that technology.

First test to access the device was successful. The following C program reads  out the firmware version number of the device.

#include <sicl.h>
#include <stdio.h>

int main(int argc, char **argv) { 
 unsigned short response; 
 unsigned short rpe;
 unsigned int ret;

 INST id = iopen("vxi,126");

 unsigned short cmd = 0xc8ff; // abort normal operation
 ret = ivxiws(id, cmd, &response, &rpe);
 if (response != 0xfffe) {
   printf("Error1: %xn", response);
   return;
 }
 cmd = 0xfcff; // begin normal operation
 ret = ivxiws(id, cmd, &response, &rpe);

 cmd = 0x7c00; // get version
 ret = ivxiws(id, cmd, &response, &rpe);
 int major = response >> 4;
 int minor = response & 0xf;
 printf("Version: %d.%dn", *major, *minor );
}

The only two SICL functions used in this low level example are iopen() and ivxiws(). iopen() opens a communication channel to the device and ivxiws() is executing the Word Serial Protocol.

The card was sold with some manuals. I hoped to get a programmer’s guide in paper or on the CD. But I got no programmers guide. At least I have the Windows 95 compiled libraries…

We have 2018, IT has moved to mystical areas today. So hey, let’s decompile the DLLs.
I checked the available free decompilers. My first try was with Snowman (LINK). It was able to decompile, but I was not able to understand the resulting C code 🙁 . After some hours of trying, I gave up.

Second try was with RetDec. The results were much more  understandable for me, but I need two days to get the first clue whats going on in the decompiled source. Each DLL decompiled in a ~40.000 line of code file.
Most of the functions were named function_0xabfdssada() or so, and so were the parameters and variables.

I searched for known command values in the C Code. I knew some of the codes from the technical guide.  Some other codes are standard codes defined by the VXI spec. All codes are 2 byte words like 0x7c00 or 0xc7ff.
After several hours of searching, I found a function in the code that inquires the firmware version from the Spectrum Analyzer. Yahoo!
Soon I found further codes, all in the Visa library. This was the first sign that that what I was trying was possible with my means.

One of the header files describe a very large struct SA9052 which contains all configuration for the device. This device is used all through the spectrum analyzer library mtcsa32.dll .
The decompiler of course did not know anything about that header file. This means an original code like:

analyzer_config->start = 0.0; // a float value

was decompiled to:

(a1 + 16) = 0;
(a1 + 20) = 0;

So it is very important to know / calculate all byte offsets in the struct. Then the decompiled code can be converted to the original lines, which are of course much more readable.

I needed 2 further days to analyze the struct byte offsets. The compiler aligns contained datataypes to addresses. E.g. a double value is 8 bytes size and its start address inside the struct must then be a multiple of 8.
If the address which would be possible as next free address (e.g. 12) is not a multiple of 8, the next higher value dividable by 8 is used as offset (here: 16). The same is true for 4 byte data types like int32 and two byte data types
like int16.

My calculated offset values were mostly correct, but not all. By analyzing the code, I found a field used by the code but not contained in the struct definition. All offsets after that missing fields were wrong. Puh!
After inserting that field in the struct definition, I could decode all assignments back to the original source code.
I can do that manually. But when looking at ~130.000 LOC, this is not possible. An automated replacement is more or less required, but currently I am still doing this manually at the code pieces I am working on.
The replacement must be quite smart and requires a C code parser…

Going forward

After having a basic understanding what to do and how to do it, I wrote a simple test program for the first API function called mr90xx_init() .

#include <sicl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <sapform.h>
#include <sa_defin.h>
#include <str_9052.h>
#include <mr_defin.h>
#include <mrapp.h>
#include "helper.h"

int main(int argc, char **argv) {
  char sessionString[50];
  ViChar message[128];
  ViStatus mr90xxStatus;
  ViSession sessionId;

  sprintf(sessionString, "vxi,126");
  mr90xxStatus = mr90xx_init(sessionString, VI_TRUE, VI_TRUE, &sessionId);
  if (mr90xxStatus != MR90XX_IE_SUCCESS) {
    printf("Error mr90xx_initn");
    exit(-1);
  } else {
    printf("mr90xx_init OKnn");
  }
}

Then I created empty files for the three decompiled DLLs named sa.c (for mrtsa32.dll), pnp.c (for mrtpnp32.dll) and visa.c for (mrtvsa32.dll). These files should contain at the end the manually changed code. I call these files the Clean Room Files.

The API function mr90xx_init() is inside mrtpnp.dll. So I copied that function to pnp.c The function calls other functions, so I copied all functions that were called by any function into the file.

By trying to compile and link my test.c , the Linker tells me what functions are still missing.

Result was that I have the complete code from the PnP DLL for the single function mr90xx_init() in a source file and not more.
Remaining are references to functions outside (to other DLLs) and to Windows APIs.

For all referenced functions in mrtsa32.dll, I did the same job and copied everything into the file sa.c. This results in a file sa.c that contains the complete code from the mrtsa32 DLL for the single function mr90xx_init() in a source file and not more.

I found that for the last library, the libvsa32.dll, the Morrow developers used another approach. There is no direct reference to VISA functions in the PnP code. They use a function table to call the transport driver function. This is a feature and allows to call different transport drivers. The driver DLL is loaded by the library depending on its configuration.

The issue here is to find the mapping and to understand how function parameters and return values are handled. I see offsets that are outside the SA9052 struct and that maybe the function pointers. But how are the functions are actually called?

At about that time I started to move my code to github. The complete project is there.

This post will be continued… newest development is always on github…