Bananen taal

Door Infant op zaterdag 14 juni 2014 18:44 - Reacties (29)
Categorien: Gepruts, Sparta: Fiets verbouwen tot het stuk gaat., Views: 11.990

Dit is in vervolg op de vorige posts:
Dooie Fiets
Banana?
Je zit nu hier:
Bananen taal
En het gaat hier verder:
Cyclic Banana Checks
Alles moet draaien
Alles moet (kapot) draaien

Deze post zal spelfouten, semi-technisch gebrabbel en eindeloze ritsen aan compleet nutteloze data bevatten. Als je daar allemaal geen zin in hebt, zou ik vooral niet verder lezen.

Ik was zover dat ik een accu en display op elkaar aansloot, en hij spontaan beeld gaf. Geweldig.
De eerst volgende stap was om er een scope aan te hangen, om een idee te krijgen wat er zo ongeveer gebeurt.
Snuf snuf
Er komen 3 draadjes uit het display zetten, de accu zet daar 5V, 24V en GND op.

De 24V lijn zou de data bus moeten voor stellen, dus dat is het eerste waar de scope wat aan mag ruiken.
Er komt gigantisch veel verkeer voorbij. Er zit wel wat structuur in, bijvoorbeeld:

Elke overgang van geen data, naar wel data, begint met het karakter 0x10.

Pakketje!


Uit de vorige post:
De Atmega die nog met 4V aan staat, geeft op de TX pin inderdaad signaal uit:
10 04 20 CC en af en toe 10 C1 21 22 80 5F.


Mooi. Het is nu toch wel 99% zeker, dat het standaard seriele communicatie is. Deze scope kan dat ook decoderen, maar om dat vervolgens allemaal met de hand te gaan zitten over krijten... daar heb ik niet zo'n zin in. Dat moet gemakkelijker kunnen.

Het eerste geschikte object wat ik op mijn plank tegen kom, is een USB naar RS-485 adapter.

RS-485 is een standaard, verzonnen in een donker verleden door een of ander instituut.

Om bitjes te kunnen lezen en zenden, heeft RS-485 twee signalen nodig die het tegenovergestelde van elkaar zijn. Als het ene signaal hoog is, en de andere laag, komt er een 1 uit zetten, en als de andere hoog is... en de ene laag, komt er een 0 uit zetten. Okee?

Die "andere" en "die ene" heten officiler A en B, en iedereen (lees: Infant) haalt ze altijd door de war:
The RS-485 signaling specification states that signal A is the inverting or '-' pin and signal B is the non-inverting or '+' pin.
This is in conflict with the A/B naming used by a number of differential transceiver manufacturers...
These manufacturers are incorrect, but their practice is in widespread use.
To avoid these confusions, some equipment manufacturers have created a third D+ and D- naming convention.

-Wiki

Okee, rant time. Kort samengevat:

De helft van de fabrikanten implementeert de standaard verkeerd. Dat vinden we met z'n allen dan onduidelijk. Vervolgens fixen we dat door de onduidelijkheid te voorzien van een nieuw label, die niet in de standaard genoemd is.

Dit is waarom elke handleiding die ik heb gelezen m.b.t. RS-485 ongeveer zo gaat:
"Sluit A op A aan, B op B. Doet ie ut niet? Draai ze om."

Anyhow, met een voeding en twee weerstanden, kan deze converter ervan overtuigd worden dat de 24V fiets bus een hele brakke RS-485 lijn is:

Weer zo'n super duidelijk schema.


Na dat zo aan te hebben gesloten, en de A en B een keer te hebben verwisseld, slinger ik mijn favoriete serial terminal aan en steek het display opnieuw in de accu.

Meteen wordt je overspoeld met een muur aan gegevens, dat gaat zo'n 10 seconden door. Het display toont de foutcode E0005 net als de vorige keer, en daarna gaat het hele zaakje uit.
code:
1
2
3
4
5
6
7
8
10 c1 21 22 06 5d 10 22 c2 22 00 ad 77 10 a4 20  .!".]."".w. 
ee 10 a4 20 ee 10 a4 20 ee 10 a4 20 ee 10 c1 21  . . . .!
22 07 cc 10 22 c2 22 00 bc 2b 10 c1 21 22 08 39  ".."".+.!".9
10 22 c2 22 00 bd ba 10 c1 21 22 09 a8 10 22 c2  .""..!".."
22 00 bf db 10 c1 21 22 0a 58 10 22 c2 22 00 c0  "..!".X."".
cb 10 04 20 cc 10 04 20 cc 10 04 20 cc 10 04 20  .. .. .. .. 
cc 10 c1 21 22 0b c9 10 22 c2 22 00 d0 06 10 c1  .!"..""...
21 22 0c fb 10 22 c2 22 00 d1 97 10 c1 21 22 0d  !".."".—.!".

Kansloos!

Dit is een stukje uit dat gelogde verkeer, om je een idee te geven. Het hele bestand staat hier.

Zoals je kunt zien, komt er geen enkel nuttig leesbaar stukje tekst in voor. Niet dat ik dit echt verwachtte.

Stap twee was dan toch maar eens de motor er op aansluiten, want daar zal hij toch ook wel mee willen babbelen? De motor heb ik helaas uit elkaar gehaald, maar de ingewanden zijn nog heel:

En dit is een motor ... hoe precies?


Dus, die draadjes vrot ik in de daarvoor bestemde connector, start een nieuwe log sessie (dataverkeer wat er bij hoort.), en wat schetst de verbazing?
OMG!


OMFSM! Een getal!

Het eerste wat je dan natuurlijk op stom geluk doet, is kijken of dat getal ergens toevallig voorbij komt vliegen.

Ik heb de data in het log in regels opgesplitst, zodat op elke regel een begin van een pakketje staat.

Meerdere malen komt 10 C1 29 26 0c 0c c3 54 c0 00 f0 59 41 21 voorbij, en dat is het enige waar 59 41 zo pats boem in voor komt. (De hex waarde van 59 41 is 17 35 of 10 3F, afhankelijk van de endianness, maar beide komen niet voor.)

Dat is vrij veel belovend, maar nog niet echt een zekerheid.

De laatste banaan die ook nog een teken van leven toonde, heb ik er toen ook maar aan gehangen en gelogd.

Deze doet het ook, en zodra het display de km stand geeft haal ik hem er weer uit. Dit display geeft 7052 km aan, en what do you know: vlak bij het einde van het log staat:

10 C1 29 26 03 0c c0 00 c0 00 f0 70 52 49

Consistentie!

Veel meer kan ik van deze opstelling natuurlijk niet maken. De "motor" gaat nooit kunnen draaien, het is berhaupt een wonder dat hier leven uit komt.

De volgende stap leek mij daarom, uitvinden of ik zelf iets tegen het display kan zeggen, bijv een andere kilometer stand. Daarvoor moet ook terug gepraat kunnen worden, en dat vereist een iets andere en wellicht ook nettere opstelling.
Terug babbelen
In plaats van het gebeunde RS-485 ding nog langer te misbruiken, heb ik een oud Olimex bordje uit de kast gehaald.

Deze heeft er een RS-232 geval erop zitten, wat weer zo'n standaard is die gewoon hetzelfde op een andere manier doet, en daar heb ik het volgende op geprikt:

Hee, een leesbaar schema.


De communicatie bus, is een los draad wat d.m.v. een pull-up weerstand(R3) op 24V gehouden wordt. Als de bus 24V is, maakt de deling R4/R5 daar ietse van 8 keer minder van (3V ongeveer) zodat dat op het ontvangst pinnetje van het RS232 ic kan zonder dat die direct in rook op gaat.

Om de bus omlaag te trekken, moet het 5V tx-signaal ge-level-shift worden naar 24V. Dat kan met twee transistoren: Als tx hoog is en Q2 in gaat, is de ingang van Q1 laag en laat hij de bus met rust. De bus is dus 24V.

Als tx laag is, wordt de ingang van Q1 hoog, en trekt hij de bus door een 100 Ohm weerstand R2 naar de GND toe. De bus is dan nog ongeveer 2V, gedeeld door c.a. 8 is dat laag genoeg om als 0 gelezen te worden.

Een nuttige feature die deze bus automatisch heeft, is dat alles wat je nu over RS-232 verzend, ook direct terug krijgt. Als twee dingen op exact hetzelfde moment op deze bus proberen te praten, kun je dat direct vast stellen, je krijgt namelijk niet hetzelfde terug als wat je er op zet.

Het bordje ziet er nu zo uit. Er zit een connector op waar het display in geprikt kan worden. En als je dat doet, gebeurt er niks.

Hm...

Misschien moet hij eerst wat aan gemasseerd worden, door er data naar toe te slingeren. Dus ik verzend het stuk waarvan ik vermoed dat het 5941 km op het display weer gaat geven:

Hallo!
Blauw is verzonden, groen is ontvangen.


Ooh!

Voor een halve seconde ofzo verschijnt inderdaad dezelfde km stand op het display, en verdwijnt daarna weer. Als ik eerst dit bericht, en daarna allemaal onzin verzend blijft het display aan, net zolang tot ik ophoud met verzenden.

Veel interessanter nog, is dat het display kennelijk antwoord geeft:
10 22 c0 26 d9.

Het versturen van het pakket met de andere km stand, geeft hetzelfde antwoord.

Dat is heel aardig, want dan kan ik wat van het gelogde verkeer op een rijtje zetten:

10 C1 29 26 0C 30 C3 54 C0 00 FC CC C0 71
10 22 D0 26 D9
10 C1 29 26 03 0C C0 00 C0 00 F0 70 52 49
10 22 C0 26 D9
10 C1 29 26 0C 30 C3 4F C0 00 FC CC C0 4E
10 22 C0 26 D9

Die gaven allemaal hetzelfde antwoord, maar er is ook:

10 C1 29 27 03 30 C0 00 00 00 3C CC C0 D4
10 22 C0 27 48
10 C1 29 27 03 00 00 00 00 00 1e 00 05 b7
10 22 c0 27 48

Bij tet verzenden van deze twee pakketjes, gaat het display niet meer uit. En kijk:

10 C1 29 27 03 00 00 00 00 00 1e 00 05 b7
10 22 c0 27 48

Deze geeft de foutcode E0005 permanent weer!

Verder komt dit bericht vaak voorbij:
10 C1 21 22 00 FE.

Het een na laatste getal loopt steeds op:
10 C1 21 22 01 6F
... 02 9F
03 0E
04 3C
05 AD
06 5D
07 CC
08 39
09 A8
0A 58
0B C9
0C FB
0D 6A
0E 9A
0F 0B

En na 0F begint hij weer opnieuw.

Dit doet sterk vermoeden dat de laatste byte een CRC is. Als ik namelijk een bit aanpas in het bericht naar het display toe, en bijv. foutcode 0004 ervan maak, gebeurt er niks, en krijg ik ook geen antwoord.

En ik wil zo graag dat het display 666km aangeeft.
CRCs
CRC's zijn geweldige dingen. Het is een controle getal wat in dit geval achter het bericht geplakt zit.

Als tijdens de verzending de data in het bericht veranderd, komt de CRC niet meer overeen. Ze zijn ontworpen om bij een kleine verandering, van. bijv maar 1 bit, een zo groot mogelijke verandering in het controle getal op te leveren.

Maar een 8-bit CRC is natuurlijk niet zo veel. 8 bits zijn 256 verschillende mogelijkheden.

Als ik zo'n bericht compleet omgooi, en er een willekeurige CRC achter bengel, heb ik een 1 op 256 kans dat ik die goed gok.

En gezien dit display zo vriendelijk is om niks te zeggen als ik puin verstuur, en netjes te antwoorden als hij het met me eens is, kan ik in theorie gewoon maar wat getallen op het eind proberen totdat het goed gaat.

Nou, dat gehele proces heb ik samengevat in een quick and dirty programmaatje.

(Mocht je het willen proberen... het werkt onder Linux of Windows + cygwin door make uit te voeren. Hij opent standaard /dev/ttyS23, maar je kunt een ander device als opstart argument mee geven. Bijv:
code:
1
./tryme /dev/ttyUSB0



Als je die opstart, vraagt hij weke waarde hij naar het display moet smijten:


Het getal wat je invoert gaat door een binare gehaktmolen heen:
C:
1
2
3
4
5
6
7
8
9
//The encoding is kinda weird, it's the HEX representation of what you see:    
 uint8_t dec[3];
 //Break it into powers of 10.
 dec[0] = speed / 100;
 dec[1] = (speed - (100*dec[0])) / 10;
 dec[2] = speed % 10;
 //Convert it to ...something
 data[8] = 0x01 * dec[0];
 data[9] = ((0x10 * dec[1])) | dec[2];


Dat propt hij op de plek waar ik ondertussen stiekem van heb uitgevonden dat het de speedo locatie is, hij laat zien wat hij verzonden heeft en wat het vorige antwoord was:


En na een aantal pogingen komt er een antwoord terug van het display:


En verschijnt het getal automagisch op het scherm!
Evil!


Enig.

We zijn nu in ieder geval op het punt beland dat je Sparta Ion display in combinatie met deze enigszins lompe manier van communiceren, kan omtoveren tot bijv een kook wekker.

Hij piept alleen niet...

Banana?

Door Infant op maandag 9 juni 2014 12:37 - Reacties (16)
Categorien: Gemod / Gefix, Sparta: Fiets verbouwen tot het stuk gaat., Views: 13.696

Ik acht mij niet verantwoordelijk voor hoge bloeddruk en/of ongecontroleerde woede aanvallen veroorzaakt door spellingfouten.

Dit is in vervolg op: Dooie Fiets - Vervolg, en gaat hier verder: Bananen Taal

Eens in de zoveel tijd struin ik rond op Marktplaats, gewapend met mijn favoriete zoektermen. Afgelopen week vond ik dat eindelijk een defecte banaan, waar ik al een hele tijd naar op zoek was. (Uiteraard was dat niet de zoekterm.) Het betreft een accu in de vorm van een banaan, voor in mijn kapotte zombie fiets.

Ik heb er drie gekocht, gezien ze zo schandalig goedkoop waren. Ze werden door een fietsen winkel aangeboden en ik kreeg er zelfs een mooie marge factuur bij opgestuurd. Ik blij, en de fietsenmaker in kwestie denk ik ook.

Hij neemt deze dingen in als iemand bij hem komt om nieuwe accu's te plaatsen.

Uiteraard mag zo'n klant dan 6 Euro verwijderingsbijdrage betalen bovenop de andere willekeurige kosten die hij in rekening gaat brengen. Normaliter moet hij dat bedrag weer afstaan aan de plek waar hij die dingen heen brengt, denk ik. De gemeente? Een donker plekje ergens in de bosjes? Chemisch afval?

In plaats daarvan krijgt hij nu nog meer geld, om het naar mij op te sturen. Een win situatie voor de de fietsenmaker, een verlies-verlies-verlies situatie voor de persoon die hem bij hem heeft ingeleverd.

Na een paar dagen komt de TNT/PostNL met een berg langwerpige dozen aan zetten:
Doosch.

De eerste 30 seconden van dit filmpje beschrijven extreem exact hoe je je dan voelt.
Open maken!
Na wat gepiel en gepeuter, gaat ook deze banaan open. Het gaat hier om een 9Ah accu, t.o.v. 10Ah , maar het printje is identiek aan degene die in mijn fiets zat. Het enige verschil is dat deze minder kapot lijkt, en helemaal geen coating heeft.

Ooh!


Uiteraard doet ook dit ding 10 keer niks.

Stiekem heb ik een tijdje geleden, toen ik me verveelde, een beginnetje gemaakt om het schema van dit printje te tekenen. Het is maar een twee-laags pcb, er zit alleen een idioot oerwoud aan analoge meuk op met weerstanden die overal overheen, naartoe en tussendoor gaan.

Ik dacht, ik begin bij de 6-pins connector, want die lijkt verdacht veel op de standaard 6-pins Atmel ISP header. Dit is de staat waarin ik het "schema" achter heb gelaten:

Hoeft niet aan elkaar?

Als je een ongesorteerde doos elektronica onderdelen zou weergeven in schema vorm, zou het er ook ongeveer zou uit zien.

Het fijne aan grote SMD onderdelen als deze (de weerstanden zijn 2 bij 1.25mm) is dat je er nog gemakkelijk draadjes aan kunt solderen. Nog handiger is dat in plaats van een idiote kleur codering, de waarde er gewoon met getallen op geschreven staat. Dus dat werk wel makkelijk.

Alle kleine zwarte onderdelen kun je niet altijd iets zinnigs over zeggen, helemaal niet als het potentieel stuk is. Een drie pootje kan een spannings regelaar, diode, mosfet of transistor zijn, en de waarde mag je raden want die staat er niet op.

Het goede nieuws is dat de 6-pins connector direct naar de programmeer pinnen van de Atmega gaat (door een 1k serie weerstand), en de voeding door een 10 Ohm weerstand op de Vcc pin aankomt. De pin-layout is niet standaard, maar een klein verloopje zit zo in elkaar.

Omdat het printje zelf geen spanning maakt, geef ik hem extern een beetje prik. Rond de 4 Volt ofzo zou moeten werken om in ieder geval met de Atmel te babbelen.

Netste opstelling tot nu toe.

Het is in de programmeer omgeving 1 keer raak: Hij wordt herkend! Jeej!

Daar houd het feestje helaas ook op. Niet geheel tegen de verwachting in zijn de lock bits ingeschakeld, wat betekend dat de applicatie niet uit het geheugen gelezen kan worden.



De chip start op in zogenaamde bootloader mode. (De BOOTRST fuse zorgt daar voor.) De lock bits staan zo ingesteld dat hij nooit de bootloader mag overschrijven, maar wel de applicatie. Als er niks ge-update hoeft te worden, wat bij normaal gebruik het geval is als je de fiets aan zeg, start hij de applicatie... en gaat hij banaan-management doen.

Deze lock-bits zijn dingen die op de chip letterlijk weg branden. Op deze wijze kunnen vervelende mensen zoals ik niet eenvoudig de applicatie uitlezen, maar kan een Sparta dealer wel de firmware in de accu updaten om er meer dubieuze en ongedocumenteerde functies in te prakken.

Op zich had iemand op het circuits online forum dit ook al bevestigd, 4 jaar geleden. Als je de chip wist, kun je wel het EEPROM uitlezen, en die inhoud heeft hij ook online gekwakt. Ik schiet daar nog niet zo veel mee op, dus ik ga deze niet wissen en laat hem verder met rust.
Hallo?!
Alle onderdelen in deze fiets praten met elkaar over een enkel geel draad, een bus. Deze staat normaal 24V op, en kan door een van de onderdelen (de motor, het display of de accu) gebruikt worden om over te communiceren.

Er is verder echt extreem weinig nuttigs te vinden over de elektronica in deze fiets, de enige hint komt wederom van CO, en die is dat er standaard USART op 9600 8N1 over die draad heen gaat.

De Atmega die nog met 4V aan staat, geeft op de TX pin inderdaad signaal uit:
10 04 20 CC en af en toe 10 C1 21 22 80 5F.

In banaan-taal zal dat hoogstwaarschijnlijk het volgende betekenen:
"Hello moto?"
"Hello display?"
(Of in andere volgorde.)

Op de ontvang pin verschijnt niks. De 24V bus wiebelt ook niet mee. Omdat de bus maar 1 enkel draad is om over te babbelen, kan deze print niet verzenden en ontvangen tegelijk. Sterker nog, als hij iets zegt op de bus hoort hij dat zelfde bericht ook weer terug. Dat is erg handig ter controle. Als de bus namelijk kapot is, zoals nu, kun je iets zeggen:
"Echo!"

En als er dan niks terug komt... weet je dat er iets niet goed is.

De communicatie vanuit het oogpunt van de microcontroller zou er normaliter (vertaald vanuit het banaans) ongeveer zo uit kunnen zien:
"Display?"
"Display?"
...
"Ja, wat is er?"
"Niks."
"Niks."
...
"Okee."

"Motor?"
"Motor?"
...
"Ja wat moet je?"

Als je geen dubbel bericht, of geen enkel antwoord terug krijgt... is er duidelijk iets mis.
In het display
De kassa forum leden klagen dat elk wissewasje een bezoekje aan de dealer vereist, die alles aan elkaar moet aanmelden via het internet.
Dit zou in houden, dat stel ik heb een werkende fiets, ik pak een willekeurige accu van Marktplaats af en prik hem er in, dan zegt de fiets: "Dat is niet mij accu, vriend." En vertikt het verder.

Verder wordt de suggestie op het CO forum gewekt dat er een of ander obscuur en horrific protocol overheen loopt, wat voorzien is van 1000 lagen encryptie, server communicatie, backdoors en andere ellende die geen enkele vorm van zinnige analyse toe staan.

Ik kan het me haast niet voorstellen. Deze accu heeft al vrij veel functies, hij moet een hele berg aan metingen doen, allerlei klant specifieke dingen bij houden, zichzelf kunnen updaten, en alles door babbelen over een enkel draad.

Dat is best een complexe applicatie. Dit ding heeft maar maar 32kB aan ruimte. (De kans bestaat dat het maar 16 kB is, als je eenvoudiger een applicatie update wilt kunnen doen.)
Stel dat je daar dat ook nog encryptie overheen wilt doen, moet je sleutels gaan zitten uit wisselen met de rest van de onderdelen.... het kan, maar ik schat de kans klein in.

Het display, wat ik vorige keer nog niet open had gemaakt, heeft verrassend weinig onderdelen:


Voorkant Achterkant

Aan de ene zijde zit een bosje passieve onderdelen, en een condensator die iemand er later tussen gevrot heeft. Aan de andere kant zitten de contactjes naar het LCD, en twee COBs.

Bijna elk LCD display wat je open maakt, in welk apparaat dan ook, heeft zo'n blob er op zitten. In 95% van de gevallen gaat het dan om een ASIC waar geen standaard verpakking omheen zit. Het chipje zit dan direct aan het PCB verbonden. Het kan ook dat ze er epoxy overheen gedaan hebben, gewoon om het je lastig te maken.

Het zou kunnen dat er een microcontroller onder de blob zit, maar ik verwacht het eigenlijk niet. Gezien er knopjes op het display zitten, en je de hele fiets met het display bedient, moet dit ook data terug kunnen sturen.

Er zit verder een stikker op, met een nummer, en met de hand is op de andere zijde... het zelfde nummer geschreven. Als er dingen op elkaar aangemeld moeten worden, zou dat wel eens voorbij kunnen komen?
Er is meer!
Ik heb nog een hele doos met bananen staan, waar nog niks mee gedaan is.

Wellicht is het nu wel interessant om te noemen dat deze bananen ongeveer 185 kCal aan energie bevatten. (10*24*3600 / 4184). En dat is ongeveer 4x zoveel als een echte banaan. :+

Alles is uiteraard ook verkocht als defect, dus ik verwacht er niet veel van. Maar de tweede uit de doos is wel het eerste exemplaar waar ik spanning op de display pinnen meet: 5V en 24V.

... :Y) ...

Nou, displaytje erin prikken op hoop van zegen dan maar.

En wederom zit het mee: Het display gaat aan! (Ik dacht eigenlijk dat die ook stuk was.) Een relais in de accu zegt tik, en de display geeft een foutcode: E0005.

Als ergens veel documentatie over te vinden is in dit project, dan zijn het wel de foutcodes. De eerste online bron heeft dit over de foutcode te zeggen:

E05: Slechte verbinding naar de motor.

No shit.

Voor mij is dit veel belovend, want zo'n melding betekend data verkeer. En data verkeer, dient gesnoven te worden... met een snuiver...