Interaction avec les moteurs (CPEFly)

Nous y voilà: l’aboutissement de mon travail de recherche. On va maintenant essayer de communiquer avec les moteurs du drone.
Si vous ne les avez pas lu, cet article fait suite à mon précédant article sur le reverse engineering du firmware du drone, disponible ici.

Petite note avant de commencer

En parallèle de ça on a bricolé un peu le châssis du drone : On a coupé le connecteur des motorboards vers la carte mère pour y ressouder des câbles. On a protégé les jonctions avec des gaines thermorétractable. On a également fixé deux breadbords sur les deux cotés du drone pour qu’on puisse y connecter tout nos câbles (capteurs, motorboards etc..).

Interactions avec les motorboards

Au niveau du circuit, je prends une sonde logique, un arduino uno et un petit breadboard. En ce qui concerne l’alimentation, je connecte le pin 5V de l’arduino à l’alimentation 5V du motorboard, le GND de l’arduino au GND du motorboard. Je connecte ensuite le TX de l’ardunio (pin 1) au RX+TX du motorboard, le pin 4 et 8 au IRQ du motorboard. Je connecte ensuite ma sonde logique sur RX+TX du motorboard (channel 0), sur IRQ (channel 1) et le GND au GND de l’arduino et du motorboard.

Je programme un petit script que je flash sur l’Arduino.

void setup() {
  
  pinMode(4, INPUT);
  pinMode(8, OUTPUT);
  blc_resetIRQ();
  delay(5000);
  blc_init();

}

void loop() {

}

void start()
{
  Serial.begin(115200,SERIAL_8N1);
}

void pause()
{
  Serial.end();
  pinMode(1, INPUT);
}
void blc_init()
{

  // Initialisation multicast
  start();
  blc_reset();
  pause();
  delay(100);
  
  start();
  blc_getVersion();
  pause();
  delay(100);
  
  start();
  blc_run_motor();
  pause();
  delay(100);

  // Initialisation moteur
  start();
  Serial.write(2);
  pause();
  delay(100);
  
  start();
  Serial.write(0x40);
  pause();
  delay(100);

  delay(1000);

  blc_startled();
  //blc_stopled();
}

void blc_run_motor()
{
  Serial.write(0xA1);
}

void blc_reset()
{
  Serial.write(0xE0);
}

void blc_getVersion()
{
  Serial.write(0x91);
}



void blc_startled()
{
  start();
  Serial.write(0x60);
  pause();
  delay(100);

  start();
  Serial.write(0x1e);
  pause();
  delay(100);
    
}

void blc_stopled()
{
  start();
  Serial.write(0x60);
  pause();
  delay(100);

  start();
  Serial.write(0x00);
  pause();
  delay(100);
    
}

void blc_multicast()
{
  for (int i = 1; i <= 6; i++) {
  start();
  Serial.write(0xa0);
  pause();
  delay(100);
  }
}

void blc_resetIRQ()
{
     if (digitalRead(4) == HIGH) {
      pinMode(8, OUTPUT);
      digitalWrite(8, LOW);
      delay(500);
      pinMode(8, INPUT);
   }
}

Pour expliquer ce que fait le script:
– On commence par set IRQ à 0 (car si il est à 1 le moteur est en mode arrêt, il ne peut pas fonctionner).
– J’envoie ensuite toutes les 5000ms une succession de commande:
* 0xE0 qui est sensé nous renvoyer l’état du moteur (0x50: le moteur a besoin d’être (re)flashé, 0x00 tout est ok)
* 0x91 qui est sensé nous renvoyer le checksum du firmware du moteur
* 0xA1 pour fixer l’état du moteur comme étant ok.
* 0x02 qui donne un ID au moteur pour les commandes multicast. Ici j’ai donné l’ID 2.
* 0x40 qui nous donne la version du moteur.
J’essaie ensuite de passer la LED en vert.
Pour rappel, voilà les commandes qu’on a réussi à récupéré lors de l’étape de reverse:

Nom de la commandeValeurDescriptionValeur de retour
Récupérer le statut du moteurE0Récupère le statut du moteur00 : ok
50 : besoin de flash la mémoire
Ecrire dans la mémoire du contrôleur du moteur71 XX…XXÉcris dans la mémoire le programme du moteur. Le programme doit faire 64 octets, représenté par les XX…XX dans la commande. La commande doit être envoyé 60 fois (60*64 octets) 70
Récupérer le checksum de la mémoire91Demande de récupérer le checksum du moteur.120 octets, correspondant au checksum de la mémoire
Initier le moteurA1« Lance » le moteurA0
Assigner un moteur comme étant le moteur 1,2,3 ou 401 ou 02 ou 03 ou 04Assigner un moteur comme étant le moteur 1,2,3 ou 400
Effacer le contenu de la mémoire61Effacer le contenu de la mémoire60
Récupérer la version du moteur40Récupérer la version du moteur sous la forme de 11 octets. Exemple : 01 0b 03 00 01 01 0a 0a 1a 0a 0a = soft version 1.11, hard version 3.0, supplier 1.1, lot number 10/10, FVT1 26/10/1011 octets

Et on obtient bien des résultats.

Des résultats certes, mais rien de bon augure. Les réponses nous indiquent que le moteur a besoin d’être (re)flash. Le checksum du moteur est très étrange et semble indiqué qu’il y a un problème.

\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0\xC0

J’essaie de rajouter des commandes pour allumer des leds, mais rien ne se passe (pas de réponse à la commande). Je décide néanmoins de tester mon code sur les 3 autres motorboard, et là…

… la LED s’allume en vert. Je peux également l’éteindre, ce qui prouve que je contrôle bien le moteur. Alors pourquoi cela ne marche pas sur ma motorboard de test ? Il est possible que lors d’un de mes tests préliminaires, j’ai envoyé la commande 0x61, ou du moins une commande qui a corrompu le firmware de ma motorboard de test. Malheureusement il faut que les 4 moteurs fonctionnent pour que le drone puisse voler. Je suis donc obligé de fixer ce petit problème, et pour cela il faut que je flash le contenue du firmware sur la motorboard.

Réparation du moteur cassé

On sait comment fonctionne la procédure de flashage du firmware sur les motorboards (on envoie 0x71 puis 64 octets, on nous répond 0x70 puis on renvoie les 120 octets etc…). Comme le firmware dont je dispose fait 7206 octets, et qu’on doit uploader au total 7680 octets, je complète avec des 0xff le reste, conformément à ce qu’on avait vu dans le firmware de la carte mère.

~/Projet-drone/decodeplf/Disk2_files » ls -la BLC.bin                                                                                                                                               ohohoh@Tempete
-rw-rw-r-- 1 ohohoh ohohoh 7206 mars  24 00:12 BLC.bin
~/Projet-drone/decodeplf/Disk2_files » xxd -p BLC.bin | sed 's/\(..\)/\\x\1/g'                                                                                                                      ohohoh@Tempete
\x12\xc0\x2c\xc0\x2b\xc0\x2a\xc0\xc5\xc3\x28\xc0\x33\xc3\x54\xc3\x57\xc3\x24\xc0\x23\xc0\x08\xc5\x21\xc0\xde\xc4\x1f\xc0
\x1e\xc0\x5e\xc3\x1c\xc0\x1b\xc0\x11\x24\x1f\xbe\xcf\xe5\xd4\xe0\xde\xbf\xcd\xbf\x11\xe0\xa0\xe6\xb0\xe0\xec\xee\xfa\xe1
\x02\xc0\x05\x90\x0d\x92\xaa\x39\xb1\x07\xd9\xf7\x12\xe0\xaa\xe9\xb1\xe0\x01\xc0\x1d\x92\xa3\x37\xb1\x07\xe1\xf7\x9f\xda
\x46\xcd\xd1\xcf\xcf\x92\xdf\x92\xef\x92\xff\x92\xcf\x93\xdf\x93\xcd\xb7\xde\xb7\x28\x97\x0f\xb6\xf8\x94\xde\xbf\x0f\xbe
\xcd\xbf\x80\x91\x3a\x02\x28\x2f\x30\xe0\x40\xe0\x50\xe0\x29\x83\x3a\x83\x4b\x83\x5c\x83\x20\x91\x3b\x02\x30\xe0\x80\x91
\x38\x02\x90\x91\x39\x02\x28\x9f\xa0\x01\x29\x9f\x50\x0d\x38\x9f\x50\x0d\x11\x24\xca\x01\xa0\xe0\xb0\xe0\x8d\x83\x9e\x83
\xaf\x83\xb8\x87\x69\x81\x7a\x81\x8b\x81\x9c\x81\x20\xec\x38\xeb\x45\xea\x5d\xe1\x8f\xdc\x2d\x81\x3e\x81\x4f\x81\x58\x85

Comme le firmware fais 7ko, et que je peux stocker des variables d’une taille maximum de 2ko sur mon arduino UNO, j’ai pris une mémoire EEPROM (24LC256) de 32ko sur laquelle je vais stocker tout le firmware, et je l’utiliserai ensuite pour flasher ma motorboard corrompue. Pour cela j’ai developpé le script ci-dessous. Il faut remplacer les macros BLOCK_NUMBER par des chiffres de 0 à 8, et lorsque BLOCK_NUMBER = 0, on fixe RESET_MEMORY à 1.

#include <I2C_eeprom.h>
#include <Wire.h>
#include <Crypto.h>
#include <SHA256.h>

#define HASH_SIZE 32

#define BLOCK_NUMBER  8
#define RESET_MEMORY  0
#define READ_ONLY     1
#define DATA_LENGTH   7206

unsigned char firmware_code[]=
#if BLOCK_NUMBER == 0
/* -------------------- 0 -------------------- */
"\x12\xc0\x2c\xc0\x2b\xc0\x2a\xc0\xc5\xc3\x28\xc0\x33\xc3\x54\xc3\x57\xc3\x24\xc0\x23\xc0\x08\xc5\x21\xc0\xde\xc4\x1f\xc0"
"\x1e\xc0\x5e\xc3\x1c\xc0\x1b\xc0\x11\x24\x1f\xbe\xcf\xe5\xd4\xe0\xde\xbf\xcd\xbf\x11\xe0\xa0\xe6\xb0\xe0\xec\xee\xfa\xe1"
"\x02\xc0\x05\x90\x0d\x92\xaa\x39\xb1\x07\xd9\xf7\x12\xe0\xaa\xe9\xb1\xe0\x01\xc0\x1d\x92\xa3\x37\xb1\x07\xe1\xf7\x9f\xda"
"\x46\xcd\xd1\xcf\xcf\x92\xdf\x92\xef\x92\xff\x92\xcf\x93\xdf\x93\xcd\xb7\xde\xb7\x28\x97\x0f\xb6\xf8\x94\xde\xbf\x0f\xbe"
"\xcd\xbf\x80\x91\x3a\x02\x28\x2f\x30\xe0\x40\xe0\x50\xe0\x29\x83\x3a\x83\x4b\x83\x5c\x83\x20\x91\x3b\x02\x30\xe0\x80\x91"
"\x38\x02\x90\x91\x39\x02\x28\x9f\xa0\x01\x29\x9f\x50\x0d\x38\x9f\x50\x0d\x11\x24\xca\x01\xa0\xe0\xb0\xe0\x8d\x83\x9e\x83"
"\xaf\x83\xb8\x87\x69\x81\x7a\x81\x8b\x81\x9c\x81\x20\xec\x38\xeb\x45\xea\x5d\xe1\x8f\xdc\x2d\x81\x3e\x81\x4f\x81\x58\x85"
"\xbd\xdc\x20\x93\x6b\x02\x30\x93\x6c\x02\x40\x93\x6d\x02\x50\x93\x6e\x02\xca\x01\xb9\x01\x20\xe0\x38\xe1\x40\xe0\x50\xe0"
"\xae\xdc\x20\x93\x2b\x02\x30\x93\x2c\x02\x40\x93\x2d\x02\x50\x93\x2e\x02\x20\x91\x5c\x02\x30\x91\x5d\x02\x40\xe0\x50\xe0"
"\x69\x81\x7a\x81\x8b\x81\x9c\x81\x68\xdc\x23\xec\x33\xe4\x40\xe0\x50\xe0\x63\xdc\x2d\x81\x3e\x81\x4f\x81\x58\x85\x91\xdc"
"\x20\x93\x6f\x02\x30\x93\x70\x02\x40\x93\x71\x02\x50\x93\x72\x02\x8f\xef\x80\x93\xa2\x01\x81\xe0\x80\x93\xa3\x01\x28\x96"
"\x0f\xb6\xf8\x94\xde\xbf\x0f\xbe\xcd\xbf\xdf\x91\xcf\x91\xff\x90\xef\x90\xdf\x90\xcf\x90\x08\x95\x80\x91\x9a\x01\x88\x23"
"\xa1\xf4\x81\xe0\x80\x93\x9a\x01\x12\xba\x11\xba\x87\xe4\x87\xbb\x82\xe0\x88\xbb\x8a\xe0\x00\x00\x81\x50\xe9\xf7\x80\xb3"
"\x80\x7b\x09\xf0\x3f\xc0\x00\xe0\x18\xba\x12\xba\x8e\xe8\x91\xe0\x61\xe0\x70\xe0\x49\xe0\x50\xe0\x94\xdc\xe1\xe6\xf0\xe0"
"\x80\xe0\x04\xc0\x8f\x5f\xf2\x96\x86\x30\x81\xf0\x90\x91\x90\x01\xdf\x01\x11\x97\x2c\x91\x29\x17\xa9\xf7\x90\x91\x91\x01"
"\x20\x81\x29\x17\x29\xf0\x8f\x5f\xf2\x96\x86\x30\x81\xf7\x80\xe0\x00\x23\x01\xf1\x88\x23\xa9\xf0\x90\xe0\x22\xe3\x30\xe0"
"\x82\x9f\xf0\x01\x83\x9f\xf0\x0d\x92\x9f\xf0\x0d\x11\x24\xa2\xe3\xb2\xe0\xe0\x5a\xff\x4f\x82\xe3\x01\x90\x0d\x92\x81\x50"
"\xe1\xf7\x2e\xdf\x08\x95\x81\xe0\x90\xe0\xe9\xcf\x80\x3b\x49\xf0\x83\xe0\x80\x93\x68\x02\xff\xcf\x81\x30\x01\xf7\x80\xe0"
"\x90\xe0\xde\xcf\x01\xe0\xb5\xcf\x84\xe0\x83\xbf\x84\xe6\x82\xbf\x89\xb7\x8e\x7f\x89\xbf\x88\xb7\x81\x60\x88\xbf\x08\x95"
"\x8a\xef\x84\xbd\x10\x92\xa0\x01\x87\xe0\x85\xbd\x12\xbc\x88\xb7\x80\x64\x88\xbf\x89\xb7\x80\x64\x89\xbf\x08\x95\x81\xe0"
"\x80\x93\xa0\x01\x89\xb7\x8f\x7b\x89\xbf\x86\xe0\x85\xbd\x8f\xef\x84\xbd\x12\xbc\x88\xb7\x80\x64\x88\xbf\x89\xb7\x80\x64"
"\x89\xbf\x08\x95\x88\xb7\x80\x64\x88\xbf\x89\xb7\x8f\x7b\x89\xbf\x08\x95\x82\xe0\x8b\xb9\x10\xbc\x88\xe0\x89\xb9\x88\xed"
"\x8a\xb9\x08\x95\x80\xb7\x88\x60\x80\xbf\x83\xe0\x88\xb9\x88\xb1\x88\x61\x88\xb9\x82\xe0\x87\xb9\x08\x95\x18\xb8\x08\x95"
"\x90\x91\x4e\x02\x92\x95\x9f\x70\x98\x0f\x90\xfd\x35\xc0\x84\xe0\x80\x93\xc4\x01\x00\x23\x09\xf0\xaa\xc0\x92\xe0\x90\x93"
"\xc5\x01\x90\x93\xc6\x01\x91\xe0\x90\x93\xc7\x01\x90\x93\xc8\x01\x80\x93\xc9\x01\x80\xe8\x80\x93\xca\x01\x80\x93\xcb\x01"
"\x80\xe2\x80\x93\xcc\x01\x80\x93\xcd\x01\x80\xe1\x80\x93\xce\x01\x80\x93\xcf\x01\x20\xea\x20\x93\xbe\x01\x90\xe9\x90\x93"
"\xbf\x01\x80\xe3\x80\x93\xc0\x01\x20\x93\xc1\x01\x90\x93\xc2\x01\x80\x93\xc3\x01\x91\xe0\x90\x93\xb8\x01\x82\xe0\x34\xc0"
"\x00\x23\x09\xf0\x4a\xc0\x82\xe0\x80\x93\xc4\x01\x94\xe0\x90\x93\xc5\x01\x90\x93\xc6\x01\x91\xe0\x90\x93\xc7\x01\x90\x93"
"\xc8\x01\x80\x93\xc9\x01\x80\xe8\x80\x93\xca\x01\x80\x93\xcb\x01\x80\xe1\x80\x93\xcc\x01\x80\x93\xcd\x01\x80\xe2\x80\x93"
"\xce\x01\x80\x93\xcf\x01\x80\xe9\x80\x93\xbe\x01\x90\xea\x90\x93\xbf\x01\x20\xe3\x20\x93\xc0\x01\x80\x93\xc1\x01\x90\x93";
#elif BLOCK_NUMBER == 1
/* -------------------- 1 -------------------- */
"\xc2\x01\x80\x93\xc3\x01\x92\xe0\x90\x93\xb8\x01\x81\xe0\x80\x93\xb9\x01\x10\x92\xba\x01\x90\x93\xbb\x01\x80\x93\xbc\x01"
"\x10\x92\xbd\x01\x9b\xe1\x90\x93\xb2\x01\x8a\xe1\x80\x93\xb3\x01\x90\x93\xb4\x01\x80\x93\xb5\x01\x90\x93\xb6\x01\x80\x93"
"\xb7\x01\x08\x95\x80\xe4\x80\x93\xc4\x01\x94\xe0\x90\x93\xc5\x01\x90\x93\xc6\x01\x91\xe0\x90\x93\xc7\x01\x90\x93\xc8\x01"
"\x80\x93\xc9\x01\x80\xe3\x80\x93\xca\x01\x80\x93\xcb\x01\x80\xea\x80\x93\xcc\x01\x80\x93\xcd\x01\x80\xe9\x80\x93\xce\x01"
"\x80\x93\xcf\x01\x80\xe1\x80\x93\xbe\x01\x90\xe2\x90\x93\xbf\x01\x90\x93\xc0\x01\x90\xe8\x90\x93\xc1\x01\x90\x93\xc2\x01"
"\x80\x93\xc3\x01\xb5\xcf\x90\xe4\x90\x93\xc5\x01\x90\x93\xc6\x01\x91\xe0\x90\x93\xc7\x01\x90\x93\xc8\x01\x80\x93\xc9\x01"
"\x80\xe3\x80\x93\xca\x01\x80\x93\xcb\x01\x80\xe9\x80\x93\xcc\x01\x80\x93\xcd\x01\x80\xea\x80\x93\xce\x01\x80\x93\xcf\x01"
"\x80\xe2\x80\x93\xbe\x01\x90\xe1\x90\x93\xbf\x01\x90\x93\xc0\x01\x90\xe8\x90\x93\xc1\x01\x90\x93\xc2\x01\x80\x93\xc3\x01"
"\x55\xcf\x33\x24\x80\xb7\x84\x60\x80\xbf\x88\xe3\x84\xbb\xab\x98\xac\x9a\xad\x9a\x81\xe0\x13\xdf\x08\x95\x89\xb7\x83\x7e"
"\x89\xbf\x1f\xbc\x1e\xbc\x18\xba\x12\xba\x11\xba\x81\xe0\x80\x93\x2f\x02\x33\x24\x44\x24\x88\x24\x55\x24\x08\x95\x10\x92"
"\x9d\x01\x10\x92\x9e\x01\x10\x92\xb1\x01\x10\x92\xb0\x01\x10\x92\xaf\x01\x10\x92\xae\x01\x10\x92\xad\x01\x10\x92\xac\x01"
"\x18\xba\x12\xba\x11\xba\x81\xe0\x80\x93\x2f\x02\x33\x24\x44\x24\x88\x24\x55\x24\x21\xe0\x30\xe0\x00\x90\x4c\x02\x02\xc0"
"\x22\x0f\x33\x1f\x0a\x94\xe2\xf7\x21\x50\x30\x40\x30\x93\x67\x02\x20\x93\x66\x02\x80\x91\x4e\x02\x81\x72\x81\x32\x09\xf4"
"\x4c\xc0\x10\x92\x65\x02\x10\x92\x64\x02\xc9\x01\x88\x0f\x99\x1f\x88\x0f\x99\x1f\x88\x0f\x99\x1f\x82\x0f\x93\x1f\x6a\xe0"
"\x70\xe0\x7d\xda\x70\x93\x6a\x02\x60\x93\x69\x02\x00\x23\x11\xf1\x80\xeb\x81\xbb\x87\xe4\x87\xbb\x80\x91\x4c\x02\x90\x91"
"\x4d\x02\x88\x30\x91\x05\x09\xf4\x45\xc0\x89\x30\x91\x05\x80\xf5\x87\x30\x91\x05\x41\xf4\x82\xe8\x8f\xbd\x89\xe1\x8e\xbd"
"\x8f\xe7\x90\xe0\x97\xbd\x86\xbd\x19\xbc\x18\xbc\x1b\xbc\x1a\xbc\x89\xb7\x84\x60\x89\xbf\x08\x95\x8c\xeb\x81\xbb\x8f\xec"
"\x87\xbb\x83\xe0\x8f\xbd\x89\xe1\x8e\xbd\x80\x91\x66\x02\x90\x91\x67\x02\x9b\xbd\x8a\xbd\x19\xbc\x18\xbc\x89\xb7\x88\x61"
"\x89\xbf\x08\x95\x88\x27\x99\x27\x82\x1b\x93\x0b\x90\x93\x65\x02\x80\x93\x64\x02\xaf\xcf\x89\x30\x91\x05\xd9\xf0\x8a\x30"
"\x91\x05\xa9\xf6\x83\xe8\x8f\xbd\x89\xe0\x8e\xbd\x19\xbc\x18\xbc\x1b\xbc\x1a\xbc\x89\xb7\x84\x60\x89\xbf\x08\x95\x81\xe8"
"\x8f\xbd\x89\xe0\x8e\xbd\x19\xbc\x18\xbc\x1b\xbc\x1a\xbc\x89\xb7\x84\x60\x89\xbf\x08\x95\x82\xe8\x8f\xbd\x89\xe0\x8e\xbd"
"\x19\xbc\x18\xbc\x1b\xbc\x1a\xbc\x89\xb7\x84\x60\x89\xbf\x08\x95\x00\x23\x51\xf0\xf8\x94\x97\xfd\x1e\xc0\x21\xe0\x20\x93"
"\x2f\x02\x9b\xbd\x8a\xbd\x78\x94\x08\x95\x9c\x01\x20\x59\x3e\x4f\x42\xe0\x21\x3e\x34\x07\x60\xf4\x10\x92\x9f\x01\xf8\x94"
"\x97\xfd\x14\xc0\x21\xe0\x20\x93\x2f\x02\x99\xbd\x88\xbd\x78\x94\x08\x95\x28\xe0\x20\x93\x9f\x01\xf2\xcf\x10\x92\x2f\x02"
"\x90\x95\x81\x95\x9f\x4f\x9b\xbd\x8a\xbd\x78\x94\x08\x95\x10\x92\x2f\x02\x90\x95\x81\x95\x9f\x4f\x99\xbd\x88\xbd\x78\x94"
"\x08\x95\xff\x93\xff\xb7\xff\x93\xf0\x91\xaa\x01\xf3\x95\xf0\x30\x09\xf4\xff\xef\xf0\x93\xaa\x01\xf0\x91\x9f\x01\xf8\xbf"
"\xf0\x91\x2f\x02\xf1\x30\x41\xf0\x33\x24\x32\xba\x38\xba\x52\xba\xff\x91\xff\xbf\xff\x91\x18\x95\x38\xba\x32\xba\x48\xba"
"\x82\xba\xff\x91\xff\xbf\xff\x91\x18\x95\x32\xba\x38\xba\x82\xba\x18\x95\xff\x93\xff\xb7\xff\x93\xf0\x91\xaa\x01\xf3\x95"
"\xf0\x30\x09\xf4\xff\xef\xf0\x93\xaa\x01\xff\x91\xff\xbf\xff\x91\x18\x95\xcf\x93\xcf\xb7\xcf\x93\xdf\x93\x9f\x93\xaf\x93"
"\xbf\x93\x33\x24\x11\x30\xb9\xf0\x13\x30\xa9\xf0\x15\x30\x99\xf0\x00\xc0\xd0\x91\xaa\x01\xc0\x91\x9d\x01\xcd\x0f\xb0\x91";
#elif BLOCK_NUMBER == 2
/* -------------------- 2 -------------------- */
"\x2a\x02\xb1\x30\x31\xf4\xc3\x30\x24\xf4\x38\xba\x43\x2c\x83\x2c\x2f\xc0\xd0\x93\x9e\x01\x24\xc0\xd0\x91\xaa\x01\xc0\x91"
"\x9e\x01\xdc\x1b\xb0\x91\x2a\x02\xb1\x30\x41\xf4\xb0\x91\xaa\x01\xb3\x30\x24\xf4\x38\xba\x43\x2c\x83\x2c\x1b\xc0\xd0\x93"
"\x9d\x01\xb0\x91\xab\x01\xb3\x95\xb6\x30\x09\xf4\xbb\x27\xb0\x93\xab\x01\xcc\xea\xd1\xe0\xcb\x0f\xd3\x1d\xb0\x91\xaa\x01"
"\xb8\x83\x30\x92\xaa\x01\xc0\x91\x31\x02\xc4\xbd\x38\xb8\xc9\xb7\xc0\x64\xc9\xbf\x06\xc0\xc0\x91\x02\x00\xc4\xbd\xc9\xb7"
"\xc0\x64\xc9\xbf\xbf\x91\xaf\x91\x9f\x91\xdf\x91\xcf\x91\xcf\xbf\xcf\x91\x18\x95\xcf\x93\xcf\xb7\xcf\x93\xdf\x93\xff\x93"
"\x33\x24\x13\x95\x16\x30\x09\xf4\x11\x27\xca\xec\xd1\xe0\xc1\x0f\xd3\x1d\x88\x80\xc4\xec\xd1\xe0\xc1\x0f\xd3\x1d\x48\x80"
"\xc0\x91\xa0\x01\xc1\x30\x81\xf0\x53\x2c\xc0\x91\x31\x02\xc4\xbd\x00\x30\x69\xf1\x38\xba\x32\xba\x81\xba\x48\xba\xff\x91"
"\xdf\x91\xcf\x91\xcf\xbf\xcf\x91\x18\x95\xf9\xb7\xff\x7b\xf9\xbf\xce\xeb\xd1\xe0\xc1\x0f\xd3\x1d\x58\x80\x00\x30\x69\xf0"
"\xd0\x91\x2f\x02\xd1\x30\x29\xf0\x38\xba\x32\xba\x81\xba\x52\xba\x04\xc0\x38\xba\x32\xba\x81\xba\x48\xba\xc8\xeb\xd1\xe0"
"\xc1\x0f\xd3\x1d\xf8\x81\xf7\xb9\xc2\xeb\xd1\xe0\xc1\x0f\xd3\x1d\xf8\x81\xf8\xb9\xff\x91\xdf\x91\xcf\x91\xcf\xbf\xcf\x91"
"\x18\x95\x00\x23\x39\xf0\x18\xba\x12\xba\x8f\xe7\x00\x00\x81\x50\xe9\xf7\x08\x95\xf8\x94\x88\x24\x44\x24\x78\x94\x8f\xe7"
"\xf6\xcf\x18\x2f\xf8\x94\x00\x23\xf9\xf0\x18\xba\x12\xba\x90\xe0\xfc\x01\xe6\x53\xfe\x4f\x20\x81\x21\xbb\x8c\x53\x9e\x4f"
"\xfc\x01\x80\x81\x88\xbb\x78\x94\x20\x91\x3e\x02\x30\x91\x3f\x02\x21\x15\x31\x05\x41\xf0\x88\xee\x93\xe0\x00\x00\x01\x97"
"\xe9\xf7\x21\x50\x30\x40\xc1\xf7\xcf\xdf\x08\x95\x90\xe0\xfc\x01\xe6\x53\xfe\x4f\x80\x80\x8c\x53\x9e\x4f\xfc\x01\x40\x80"
"\x78\x94\xe4\xcf\xf8\x94\x80\x90\xca\x01\xe8\x2f\xf0\xe0\xec\x53\xfe\x4f\x40\x80\x78\x94\x8e\xef\x00\x00\x81\x50\xe9\xf7"
"\x08\x95\x81\xe0\x9f\xef\x9c\xde\x8f\xef\x80\x93\xa2\x01\x21\xe0\x20\x93\xa3\x01\x80\x91\xa8\x01\x90\x91\xa9\x01\x00\x97"
"\x29\xf1\xab\x9a\xac\x98\xad\x98\x83\xe0\x80\x93\x68\x02\x10\x92\x30\x02\x80\x91\xa3\x01\x80\x6c\x80\x93\xa3\x01\x20\x93"
"\xa1\x01\x28\xe2\x30\xe0\x88\xee\x93\xe0\x00\x00\x01\x97\xe9\xf7\x21\x50\x30\x40\xc1\xf7\xc8\xdc\xad\xdc\xb6\xdd\x10\x92"
"\xa7\x01\x10\x92\xa6\x01\x10\x92\xa4\x01\x10\x92\xa5\x01\x08\x95\x10\x92\x68\x02\x20\x93\x30\x02\x80\x91\xa3\x01\x80\x93"
"\xa3\x01\xe1\xcf\x80\x91\xfc\x01\x88\x23\x11\xf5\x80\x91\x97\x01\x90\x91\x98\x01\x01\x97\x90\x93\x98\x01\x80\x93\x97\x01"
"\x00\x97\x91\xf5\xac\x9a\xad\x98\x8a\xb1\x8f\x73\x8a\xb9\x80\x91\xf9\x01\x82\x30\x11\xf0\x10\x92\xf9\x01\x10\x92\xd2\x01"
"\x10\x92\xd1\x01\x8a\xb1\x80\x6c\x8a\xb9\x10\x92\xa9\x01\x10\x92\xa8\x01\x08\x95\x80\x91\x30\x02\x83\x30\xc0\xf0\x88\xe5"
"\x92\xe0\x90\x93\x98\x01\x80\x93\x97\x01\x8a\xb1\x8f\x73\x8a\xb9\x80\x91\xfa\x01\x90\x91\xfb\x01\x90\x93\xa9\x01\x80\x93"
"\xa8\x01\x8a\xb1\x80\x6c\x8a\xb9\x35\xd2\x10\x92\xfc\x01\x08\x95\x8e\xe1\x90\xe0\x90\x93\x98\x01\x80\x93\x97\x01\xe7\xcf"
"\x1f\x92\x0f\x92\x0f\xb6\x0f\x92\x11\x24\x8f\x93\x9f\x93\xef\x93\xff\x93\x90\x91\xd1\x01\x80\x91\xd2\x01\x98\x17\x81\xf0"
"\x80\x91\xd1\x01\xe8\x2f\xf0\xe0\xed\x52\xfe\x4f\x90\x81\x9c\xb9\x8f\x5f\x80\x93\xd1\x01\x80\x91\xd1\x01\x8f\x71\x80\x93"
"\xd1\x01\xff\x91\xef\x91\x9f\x91\x8f\x91\x0f\x90\x0f\xbe\x0f\x90\x1f\x90\x18\x95\x1f\x92\x0f\x92\x0f\xb6\x0f\x92\x11\x24"
"\x2f\x93\x3f\x93\x4f\x93\x5f\x93\x8f\x93\x9f\x93\xaf\x93\xbf\x93\xef\x93\xff\x93\x8c\xb1\x80\x93\xf7\x01\x80\x91\xf9\x01"
"\x88\x23\xb9\xf5\x80\x91\xf7\x01\x82\x95\x86\x95\x87\x70\x80\x93\xf8\x01\x10\x92\xfd\x01\x80\x91\xf8\x01\x88\x30\xd8\xf5"
"\x80\x91\xf8\x01\x81\x30\x09\xf4\x7e\xc0\x80\x91\xf8\x01\x83\x30\x09\xf4\x55\xc0\x40\x91\xf8\x01\x42\x30\x09\xf4\x78\xc0";
#elif BLOCK_NUMBER == 3
/* -------------------- 3 -------------------- */
"\x43\x30\x08\xf0\x5a\xc0\x44\x23\x09\xf4\xb4\xc0\x41\x30\x09\xf0\x74\xc0\x50\x91\xd0\x01\x52\x30\x09\xf4\x2b\xc1\x53\x30"
"\x08\xf0\xfe\xc0\x51\x30\x09\xf4\x41\xc1\x10\x92\xfb\x01\x10\x92\xfa\x01\x40\x91\xfd\x01\x64\xc0\x80\x91\xf9\x01\x81\x30"
"\xe1\xf0\x80\x91\xf9\x01\x82\x30\x49\xf4\x80\x91\xfd\x01\x81\x50\x80\x93\xfd\x01\x88\x23\x11\xf4\x10\x92\xf9\x01\xff\x91"
"\xef\x91\xbf\x91\xaf\x91\x9f\x91\x8f\x91\x5f\x91\x4f\x91\x3f\x91\x2f\x91\x0f\x90\x0f\xbe\x0f\x90\x1f\x90\x18\x95\x80\x91"
"\xfe\x01\x90\x91\xf7\x01\xe8\x2f\xf0\xe0\xe1\x50\xfe\x4f\x90\x83\x8f\x5f\x80\x93\xfe\x01\x80\x91\xfd\x01\x81\x50\x80\x93"
"\xfd\x01\x88\x23\x09\xf4\xac\xcf\xdc\xcf\x81\xe0\x80\x93\xfd\x01\x81\xe0\x80\x93\xf9\x01\x80\x93\xfe\x01\x80\x91\xf7\x01"
"\x80\x93\xff\x01\xcf\xcf\x44\x30\x09\xf4\x88\xc0\x44\x30\x08\xf0\x73\xc0\x80\x91\xf5\x01\x90\x91\x00\x02\x89\x23\x09\xf4"
"\xa3\xc0\xac\x98\x80\x91\xf5\x01\x90\x91\xff\x01\x89\x23\x09\xf4\x99\xc0\xad\x98\x09\xc0\x84\xe0\x80\x93\xfd\x01\xdb\xcf"
"\x80\x91\x30\x02\x82\x30\x08\xf4\xb1\xc0\x40\x91\xfd\x01\x44\x23\x09\xf4\xa8\xcf\xe0\x91\x07\x02\xf0\x91\x08\x02\x80\x91"
"\xd1\x01\x90\x91\xd2\x01\x81\x50\x89\x1b\x18\x16\x0c\xf0\x57\xc0\x24\x2f\x30\xe0\x99\x27\x87\xfd\x90\x95\x82\x17\x93\x07"
"\xfc\xf0\x90\x91\xd2\x01\x80\x91\xd1\x01\x98\x17\x09\xf4\x65\xc0\x41\x50\xcf\x01\x84\x0f\x91\x1d\x01\x96\x20\x91\xd2\x01"
"\xa2\x2f\xb0\xe0\x31\x91\xad\x52\xbe\x4f\x3c\x93\x2f\x5f\x20\x93\xd2\x01\x20\x91\xd2\x01\x2f\x71\x20\x93\xd2\x01\xe8\x17"
"\xf9\x07\x69\xf7\x82\xe0\x80\x93\xf9\x01\x72\xcf\x80\x91\xd0\x01\x88\x23\x09\xf0\xbe\xcf\x80\x91\xf7\x01\x87\x70\x80\x93"
"\xd0\x01\x80\x91\xd0\x01\x85\x30\x10\xf0\x10\x92\xd0\x01\x20\x91\xd0\x01\x81\xe0\x90\xe0\x02\xc0\x88\x0f\x99\x1f\x2a\x95"
"\xe2\xf7\x80\x93\xf5\x01\xa7\xcf\x47\x30\x09\xf0\xa4\xcf\x10\x92\xf8\x01\x81\xe0\x80\x93\xfd\x01\x88\xef\x91\xe0\x90\x93"
"\x08\x02\x80\x93\x07\x02\x41\xe0\x9c\xcf\x80\x5e\xa7\xcf\x20\x91\xd0\x01\x80\x91\xf7\x01\x30\xe0\x90\xe0\x87\x70\x90\x70"
"\x28\x17\x39\x07\x09\xf0\x89\xcf\x82\xe0\x80\x93\xfd\x01\x80\x91\xf7\x01\x83\xff\x88\xc0\x82\xea\x91\xe0\x90\x93\x08\x02"
"\x80\x93\x07\x02\x42\xe0\x7f\xcf\x80\x81\x8c\xb9\x41\x30\x09\xf4\xae\xcf\x31\x96\x42\x50\x94\xcf\xad\x9a\x70\xcf\xac\x9a"
"\x5c\xcf\x53\x30\x09\xf4\x5e\xc0\x54\x30\x09\xf0\xff\xce\x80\x91\x02\x02\x90\xe0\x83\x70\x90\x70\x96\x95\x98\x2f\x88\x27"
"\x97\x95\x87\x95\x20\x91\x03\x02\x26\x95\x30\xe0\x82\x2b\x93\x2b\x90\x93\xfb\x01\x80\x93\xfa\x01\x40\x93\xfc\x01\x40\x91"
"\xfd\x01\x51\xcf\x8b\xe0\x80\x93\xfd\x01\x8c\xe8\x91\xe0\x90\x93\x08\x02\x80\x93\x07\x02\x4b\xe0\x49\xcf\x80\x91\x00\x02"
"\x90\xe0\x8f\x70\x90\x70\x88\x0f\x99\x1f\x82\x95\x92\x95\x90\x7f\x98\x27\x80\x7f\x98\x27\x20\x91\x01\x02\x26\x95\x26\x95"
"\x26\x95\x30\xe0\x82\x2b\x93\x2b\x90\x93\xfb\x01\x80\x93\xfa\x01\x40\x93\xfc\x01\x28\xcf\x80\x91\xff\x01\x90\xe0\x8f\x71"
"\x90\x70\x82\x95\x92\x95\x90\x7f\x98\x27\x80\x7f\x98\x27\x20\x91\x00\x02\x22\x95\x2f\x70\x30\xe0\x82\x2b\x93\x2b\x90\x93"
"\xfb\x01\x80\x93\xfa\x01\x50\x93\xfc\x01\x40\x91\xfd\x01\x0f\xcf\x80\x91\x01\x02\x90\xe0\x87\x70\x90\x70\x00\x24\x96\x95"
"\x87\x95\x07\x94\x96\x95\x87\x95\x07\x94\x98\x2f\x80\x2d\x20\x91\x02\x02\x26\x95\x26\x95\xc8\xcf\x84\xea\x91\xe0\x90\x93"
"\x08\x02\x80\x93\x07\x02\x42\xe0\xf7\xce\x10\x92\x09\x02\x10\x92\x0a\x02\x10\x92\x0b\x02\x10\x92\x0c\x02\x80\xe2\x80\x93"
"\x0d\x02\x10\x92\x0e\x02\x10\x92\x0f\x02\x10\x92\x10\x02\x10\x92\x11\x02\x10\x92\x12\x02\x10\x92\x13\x02\x10\x92\x14\x02"
"\x10\x92\x15\x02\x80\x91\xa6\x01\x90\x91\xa7\x01\xa0\xe0\xb0\xe0\x80\x93\x16\x02\x90\x93\x17\x02\xa0\x93\x18\x02\xb0\x93"
"\x19\x02\x80\x93\x1a\x02\x90\x93\x1b\x02\xa0\x93\x1c\x02\xb0\x93\x1d\x02\x10\x92\x1f\x02\x10\x92\x1e\x02\x10\x92\x21\x02";
#elif BLOCK_NUMBER == 4
/* -------------------- 4 -------------------- */
"\x10\x92\x20\x02\x88\xec\x90\xe0\x90\x93\x23\x02\x80\x93\x22\x02\x8f\xef\x91\xe0\x90\x93\x25\x02\x80\x93\x24\x02\x08\x95"
"\x40\x91\x20\x02\x50\x91\x21\x02\x50\x93\x1f\x02\x40\x93\x1e\x02\x9a\x01\x22\x0f\x33\x1f\x24\x0f\x35\x1f\xc9\x01\x88\x0f"
"\x99\x1f\x88\x0f\x99\x1f\x82\x0f\x93\x1f\x20\x91\xa8\x01\x30\x91\xa9\x01\x82\x0f\x93\x1f\x92\x95\x82\x95\x8f\x70\x89\x27"
"\x9f\x70\x89\x27\x90\x93\x21\x02\x80\x93\x20\x02\x48\x17\x59\x07\x3c\xf0\x48\x1b\x59\x0b\x50\x93\x27\x02\x40\x93\x26\x02"
"\x08\x95\x84\x1b\x95\x0b\x90\x93\x27\x02\x80\x93\x26\x02\x08\x95\xcf\x92\xdf\x92\xef\x92\xff\x92\x80\x91\xac\x01\xc0\x90"
"\xad\x01\xdd\x24\xc8\x0e\xd1\x1c\x80\x91\xae\x01\xc8\x0e\xd1\x1c\x80\x91\xaf\x01\xc8\x0e\xd1\x1c\x80\x91\xb0\x01\xc8\x0e"
"\xd1\x1c\x80\x91\xb1\x01\xc8\x0e\xd1\x1c\xee\x24\xff\x24\x80\x91\x4c\x02\x81\x50\x04\xc0\xcc\x0c\xdd\x1c\xee\x1c\xff\x1c"
"\x8a\x95\xd2\xf7\xc1\x14\xd1\x04\xe1\x04\xf1\x04\x29\xf4\x31\xe0\xc3\x2e\xd1\x2c\xe1\x2c\xf1\x2c\x60\x91\x6b\x02\x70\x91"
"\x6c\x02\x80\x91\x6d\x02\x90\x91\x6e\x02\xa7\x01\x96\x01\x9f\xd5\x80\x91\x58\x02\x90\x91\x59\x02\xa0\xe0\xb0\xe0\x28\x17"
"\x39\x07\x4a\x07\x5b\x07\x60\xf0\x80\x91\x5a\x02\x90\x91\x5b\x02\xa0\xe0\xb0\xe0\x82\x17\x93\x07\xa4\x07\xb5\x07\x08\xf0"
"\x63\xc0\x81\xe0\x90\xe0\x90\x93\xa7\x01\x80\x93\xa6\x01\x8a\xb1\x8f\x73\x8a\xb9\x90\x91\xa6\x01\x80\x91\xa7\x01\x90\x93"
"\xa4\x01\x80\x93\xa5\x01\x8a\xb1\x80\x6c\x8a\xb9\xc0\x90\x1a\x02\xd0\x90\x1b\x02\xe0\x90\x1c\x02\xf0\x90\x1d\x02\xc0\x92"
"\x16\x02\xd0\x92\x17\x02\xe0\x92\x18\x02\xf0\x92\x19\x02\xd7\x01\xc6\x01\x88\x0f\x99\x1f\xaa\x1f\xbb\x1f\x88\x0f\x99\x1f"
"\xaa\x1f\xbb\x1f\x88\x0f\x99\x1f\xaa\x1f\xbb\x1f\x88\x0f\x99\x1f\xaa\x1f\xbb\x1f\x8c\x19\x9d\x09\xae\x09\xbf\x09\x40\x91"
"\xa6\x01\x50\x91\xa7\x01\x60\xe0\x70\xe0\x84\x0f\x95\x1f\xa6\x1f\xb7\x1f\x24\xe0\xb6\x95\xa7\x95\x97\x95\x87\x95\x2a\x95"
"\xd1\xf7\x80\x93\x1a\x02\x90\x93\x1b\x02\xa0\x93\x1c\x02\xb0\x93\x1d\x02\xc8\x16\xd9\x06\xea\x06\xfb\x06\x84\xf0\xc8\x1a"
"\xd9\x0a\xd0\x92\x29\x02\xc0\x92\x28\x02\xff\x90\xef\x90\xdf\x90\xcf\x90\x08\x95\x30\x93\xa7\x01\x20\x93\xa6\x01\x9e\xcf"
"\x8c\x19\x9d\x09\x90\x93\x29\x02\x80\x93\x28\x02\xff\x90\xef\x90\xdf\x90\xcf\x90\x08\x95\x80\x91\x4e\x02\x83\xff\x21\xc0"
"\x20\x91\xa6\x01\x30\x91\xa7\x01\x80\x91\x36\x02\x90\x91\x37\x02\x82\x17\x93\x07\xb0\xf4\x40\xe0\x50\xe0\x60\x91\x6f\x02"
"\x70\x91\x70\x02\x80\x91\x71\x02\x90\x91\x72\x02\xfb\xd4\xc9\x01\x2f\x3f\x31\x05\x09\xf0\x60\xf4\x80\x95\xf8\x94\x80\x93"
"\x31\x02\x78\x94\x08\x95\xf8\x94\x8f\xef\x80\x93\x31\x02\x78\x94\x08\x95\x8f\xef\x90\xe0\x80\x95\xf8\x94\x80\x93\x31\x02"
"\x78\x94\x08\x95\xaf\x92\xbf\x92\xcf\x92\xdf\x92\xef\x92\xff\x92\xcf\x93\xdf\x93\xec\x01\x5b\x01\xc0\x90\x1a\x02\xd0\x90"
"\x1b\x02\xe0\x90\x1c\x02\xf0\x90\x1d\x02\x20\x91\x60\x02\x30\x91\x61\x02\x40\xe0\x50\xe0\xc7\x01\xb6\x01\xe9\xd4\x80\x91"
"\x62\x02\x90\x91\x63\x02\xb9\x01\x68\x1b\x79\x0b\xcb\x01\x88\x0f\x99\x1f\x20\x91\x28\x02\x30\x91\x29\x02\x28\x17\x39\x07"
"\x60\xf1\xc7\x01\xb6\x01\x28\xee\x33\xe0\x40\xe0\x50\xe0\xd1\xd4\xc9\x01\x01\x96\x20\x91\x26\x02\x30\x91\x27\x02\x28\x17"
"\x39\x07\x08\xf4\x46\xc0\x1c\x16\x1d\x06\x0c\xf0\x4c\xc0\xd6\x95\xc7\x95\x24\x96\xd0\x93\x23\x02\xc0\x93\x22\x02\x80\x91"
"\xa8\x01\x90\x91\xa9\x01\x00\x97\xb1\xf4\xd2\xdb\xdf\x91\xcf\x91\xff\x90\xef\x90\xdf\x90\xcf\x90\xbf\x90\xaf\x90\x08\x95"
"\x84\xe0\x90\xe0\x90\x93\x23\x02\x80\x93\x22\x02\x80\x91\xa8\x01\x90\x91\xa9\x01\x00\x97\x51\xf3\x80\x91\x4e\x02\x81\xff"
"\x18\xc0\x80\x91\xa6\x01\x90\x91\xa7\x01\x20\x91\x5a\x02\x30\x91\x5b\x02\x82\x17\x93\x07\xd8\xf6\x20\x91\x58\x02\x30\x91"
"\x59\x02\x28\x17\x39\x07\xa0\xf6\x80\x91\x22\x02\x90\x91\x23\x02\x00\x97\x71\xf2\xc5\x01\x3e\xda\xcc\xcf\x80\x91\x22\x02";
#elif BLOCK_NUMBER == 5
/* -------------------- 5 -------------------- */
"\x90\x91\x23\x02\x01\x97\x90\x93\x23\x02\x80\x93\x22\x02\xd1\xcf\xd0\x95\xc1\x95\xdf\x4f\xb0\xcf\x6f\x92\x7f\x92\xaf\x92"
"\xbf\x92\xcf\x92\xdf\x92\xef\x92\xff\x92\xcf\x93\xdf\x93\xcd\xb7\xde\xb7\x2a\x97\x0f\xb6\xf8\x94\xde\xbf\x0f\xbe\xcd\xbf"
"\x7a\x87\x69\x87\x20\x91\x50\x02\x30\x91\x51\x02\x40\xe0\x50\xe0\x6c\x01\xee\x24\xd7\xfc\xe0\x94\xfe\x2c\xc9\x82\xda\x82"
"\xeb\x82\xfc\x82\xc7\x01\xb6\x01\xf8\xd3\x6d\x83\x7e\x83\x8f\x83\x98\x87\x80\x91\x0e\x02\x90\x91\x0f\x02\xa0\x91\x10\x02"
"\xb0\x91\x11\x02\x60\x90\x64\x02\x70\x90\x65\x02\xa3\x01\x66\x27\x57\xfd\x60\x95\x76\x2f\x48\x17\x59\x07\x6a\x07\x7b\x07"
"\x0c\xf4\xb9\xc0\xc0\x90\x09\x02\xd0\x90\x0a\x02\xe0\x90\x0b\x02\xf0\x90\x0c\x02\xa0\x90\x66\x02\xb0\x90\x67\x02\x31\xe4"
"\xc3\x16\x32\xe4\xd3\x06\x3f\xe0\xe3\x06\x30\xe0\xf3\x06\x0c\xf4\xc9\xc0\x80\xe4\x92\xe4\xaf\xe0\xb0\xe0\x80\x93\x09\x02"
"\x90\x93\x0a\x02\xa0\x93\x0b\x02\xb0\x93\x0c\x02\xf0\xe4\xcf\x2e\xf2\xe4\xdf\x2e\xff\xe0\xef\x2e\xf1\x2c\x60\x91\x52\x02"
"\x70\x91\x53\x02\x80\xe0\x90\xe0\xa7\x01\x96\x01\xab\xd3\xcd\x80\xde\x80\xef\x80\xf8\x84\x6c\x0d\x7d\x1d\x8e\x1d\x9f\x1d"
"\x20\x91\x56\x02\x30\x91\x57\x02\x40\xe0\x50\xe0\xf1\xd3\x2d\x83\x3e\x83\x4f\x83\x58\x87\xca\x01\xb9\x01\x24\xed\x33\xe0"
"\x40\xe0\x50\xe0\x91\xd3\x6b\x01\x7c\x01\x60\x91\x12\x02\x70\x91\x13\x02\x80\x91\x14\x02\x90\x91\x15\x02\x2e\xef\x31\xe0"
"\x40\xe0\x50\xe0\x82\xd3\xdc\x01\xcb\x01\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\xc7\x01\xb6\x01\x20\xe0\x34\xe0\x40\xe0\x50\xe0"
"\xca\xd3\x29\x83\x3a\x83\x4b\x83\x5c\x83\x20\x93\x12\x02\x30\x93\x13\x02\x40\x93\x14\x02\x50\x93\x15\x02\xe9\x84\xfa\x84"
"\xc7\x01\xaa\x27\x97\xfd\xa0\x95\xba\x2f\x01\x30\x09\xf4\xc4\xc0\x20\x91\x32\x02\x22\x23\x09\xf4\x7b\xc0\xc9\x80\xda\x80"
"\xeb\x80\xfc\x80\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\xc0\x92\x0e\x02\xd0\x92\x0f\x02\xe0\x92\x10\x02\xf0\x92\x11\x02\xc5\x01"
"\xa0\xe0\xb0\xe0\x8c\x15\x9d\x05\xae\x05\xbf\x05\x0c\xf4\xa4\xc0\xc3\x01\xa3\x01\x66\x27\x57\xfd\x60\x95\x76\x2f\xc4\x16"
"\xd5\x06\xe6\x06\xf7\x06\x0c\xf0\xc6\x01\x2a\x96\x0f\xb6\xf8\x94\xde\xbf\x0f\xbe\xcd\xbf\xdf\x91\xcf\x91\xff\x90\xef\x90"
"\xdf\x90\xcf\x90\xbf\x90\xaf\x90\x7f\x90\x6f\x90\x08\x95\xa0\x90\x66\x02\xb0\x90\x67\x02\xa5\x01\x60\xe0\x70\xe0\xc0\x90"
"\x09\x02\xd0\x90\x0a\x02\xe0\x90\x0b\x02\xf0\x90\x0c\x02\x84\x17\x95\x07\xa6\x07\xb7\x07\x0c\xf0\x3e\xcf\x29\x81\x3a\x81"
"\x4b\x81\x5c\x81\xc2\x0e\xd3\x1e\xe4\x1e\xf5\x1e\xc0\x92\x09\x02\xd0\x92\x0a\x02\xe0\x92\x0b\x02\xf0\x92\x0c\x02\x2d\xcf"
"\x40\xec\xc4\x16\x4d\xeb\xd4\x06\x40\xef\xe4\x06\x4f\xef\xf4\x06\x0c\xf0\x40\xcf\x80\xec\x9d\xeb\xa0\xef\xbf\xef\x80\x93"
"\x09\x02\x90\x93\x0a\x02\xa0\x93\x0b\x02\xb0\x93\x0c\x02\xe0\xec\xce\x2e\xed\xeb\xde\x2e\xe0\xef\xee\x2e\xef\xef\xfe\x2e"
"\x2b\xcf\x29\x85\x3a\x85\xa9\x01\xcc\xd2\x28\xea\x3d\xef\x4f\xef\x5f\xef\x2b\xd3\x69\x01\x7a\x01\x2d\x81\x3e\x81\x4f\x81"
"\x58\x85\xc2\x0e\xd3\x1e\xe4\x1e\xf5\x1e\x89\x85\x9a\x85\x88\x0f\x99\x1f\x88\x0f\x99\x1f\x88\x0f\x99\x1f\x49\x85\x5a\x85"
"\x84\x0f\x95\x1f\x65\xe0\x70\xe0\xdc\xd2\xcb\x01\xa0\xe0\xb0\xe0\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\x8d\xea\x9f\xef\xaf\xef"
"\xbf\xef\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\xc0\x92\x0e\x02\xd0\x92\x0f\x02\xe0\x92\x10\x02\xf0\x92\x11\x02\xc5\x01\xa0\xe0"
"\xb0\xe0\x8c\x15\x9d\x05\xae\x05\xbf\x05\x0c\xf0\x5c\xcf\xc5\x01\x66\xcf\x97\x01\xa7\x01\x89\xd2\x28\xe8\x33\xe1\x40\xe0"
"\x50\xe0\xe8\xd2\x69\x01\x7a\x01\x29\x81\x3a\x81\x4b\x81\x5c\x81\xc2\x0e\xd3\x1e\xe4\x1e\xf5\x1e\x89\x85\x9a\x85\x88\x0f"
"\x99\x1f\x65\xe0\x70\xe0\xa1\xd2\xcb\x01\xa0\xe0\xb0\xe0\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\x83\xed\x9f\xef\xaf\xef\xbf\xef"
"\xc8\x0e\xd9\x1e\xea\x1e\xfb\x1e\xc0\x92\x0e\x02\xd0\x92\x0f\x02\xe0\x92\x10\x02\xf0\x92\x11\x02\x20\xcf\x20\x91\x69\x02";
#elif BLOCK_NUMBER == 6
/* -------------------- 6 -------------------- */
"\x30\x91\x6a\x02\x28\x17\x39\x07\xc0\xf4\x80\x91\x0d\x02\x88\x23\x99\xf5\x80\x91\xa6\x01\x90\x91\xa7\x01\x20\x91\x36\x02"
"\x30\x91\x37\x02\x82\x1b\x93\x0b\x60\x91\x3c\x02\x70\x91\x3d\x02\x6f\xd2\x70\x93\x25\x02\x60\x93\x24\x02\x09\xc0\x8f\xef"
"\x91\xe0\x90\x93\x25\x02\x80\x93\x24\x02\x80\xe2\x80\x93\x0d\x02\x8a\xb1\x8f\x73\x8a\xb9\x80\x91\x24\x02\x90\x91\x25\x02"
"\x80\x93\xa2\x01\x80\x91\x68\x02\x82\x95\x88\x0f\x88\x0f\x80\x7c\x89\x2b\x80\x93\xa3\x01\x8a\xb1\x80\x6c\x8a\xb9\x08\x95"
"\x81\x50\x80\x93\x0d\x02\xe6\xcf\xcf\x93\xdf\x93\x00\xd0\x00\xd0\xcd\xb7\xde\xb7\x68\xd7\xdd\xd5\x6f\xd6\x3c\xd6\x78\x94"
"\x81\xe0\x80\x93\x30\x02\xaa\x24\xbb\x24\x66\x24\x77\x24\xee\x24\xff\x24\x1a\x82\x19\x82\x50\xe3\xd5\x2e\x64\xe0\xc6\x2e"
"\x70\xe4\x97\x2e\x80\x91\x30\x02\x88\x23\x09\xf4\xe1\xc0\x22\x24\x23\x94\x80\x91\x30\x02\x81\x30\x09\xf0\x70\xc0\x08\xb6"
"\x00\xfe\xfd\xcf\x34\xe6\x32\xbf\x88\xb7\x81\x60\x88\xbf\xa6\xd9\x80\x91\xd0\x01\x00\x23\x09\xf0\xf0\xc0\x88\x23\x29\xf0"
"\x80\x91\x9b\x01\x88\x23\x09\xf4\x3c\xc1\x80\x91\xd0\x01\x88\x23\x69\xf0\x80\x91\xa8\x01\x90\x91\xa9\x01\x00\x97\x39\xf0"
"\x80\x91\xa1\x01\x88\x23\x19\xf4\x08\x94\xe1\x1c\xf1\x1c\xf5\xe6\xef\x16\xf1\x04\x88\xf2\x10\xd5\x82\xe0\x80\x93\x30\x02"
"\x20\x92\x68\x02\x8f\xef\x80\x93\xa2\x01\x81\xe4\x80\x93\xa3\x01\x85\xe0\x80\x93\xab\x01\x10\x92\x2a\x02\x10\x92\xa7\x01"
"\x10\x92\xa6\x01\x10\x92\xa5\x01\x10\x92\xa4\x01\x1f\xd7\x80\x91\xd0\x01\x81\x30\x29\xf0\x80\x91\xd0\x01\x83\x30\x09\xf0"
"\x36\xc1\x81\xe0\x16\xd6\x80\x91\x40\x02\x90\x91\x41\x02\xbd\xd7\x80\xe0\xe0\xd8\x81\xe0\xde\xd8\x20\x91\x46\x02\x30\x91"
"\x47\x02\x3a\x83\x29\x83\xca\xd5\x80\x91\x42\x02\x90\x91\x43\x02\xad\xd7\x88\xef\x82\xbf\x88\xb7\x81\x60\x88\xbf\xee\x24"
"\xff\x24\x80\x91\x30\x02\x81\x30\x09\xf4\x90\xcf\x43\xe0\x24\x2e\x80\x91\x30\x02\x82\x30\x09\xf0\x43\xc0\x08\xb6\x00\xfe"
"\xfd\xcf\x34\xe6\x32\xbf\x88\xb7\x81\x60\x88\xbf\x2f\xd9\x69\x81\x7a\x81\x9b\x01\x40\xe0\x50\xe0\x60\x91\x2b\x02\x70\x91"
"\x2c\x02\x80\x91\x2d\x02\x90\x91\x2e\x02\xa5\xd1\x2f\x3f\x31\x05\x11\xf0\x08\xf0\xf3\xc0\x7f\xef\x72\x1b\x87\x2f\x80\x93"
"\x31\x02\x80\x91\x4a\x02\x90\x91\x4b\x02\xe9\x81\xfa\x81\xe8\x0f\xf9\x1f\xfa\x83\xe9\x83\x80\x91\x48\x02\x90\x91\x49\x02"
"\xe8\x17\xf9\x07\x48\xf2\x20\x92\x30\x02\xac\xd5\x80\x91\x44\x02\x90\x91\x45\x02\x60\xd7\x97\xd5\x84\xd5\xee\x24\xff\x24"
"\x80\x91\x30\x02\x82\x30\x09\xf4\xbd\xcf\x22\x24\x2a\x94\x80\x91\x30\x02\x83\x30\x09\xf0\xe4\xc0\x08\xb6\x00\xfe\xfd\xcf"
"\xf8\xef\xf2\xbf\x88\xb7\x81\x60\x88\xbf\xe5\xd8\x8d\xdb\x08\x94\xe1\x1c\xf1\x1c\x21\xe0\xe2\x16\x22\xe0\xf2\x06\x08\xf0"
"\xb4\xc0\x32\xe0\xe3\x16\xf1\x04\x21\xf7\x04\xdb\xe2\xcf\x08\xb6\x00\xfe\xfd\xcf\x24\xe6\x22\xbf\x88\xb7\x81\x60\x88\xbf"
"\xcc\xd8\x80\x91\xa8\x01\x90\x91\xa9\x01\x00\x97\x09\xf0\x0a\xcf\x10\x92\xa1\x01\xab\x98\x10\x92\x68\x02\x81\xe0\x80\x93"
"\x30\x02\x10\x92\xa7\x01\x10\x92\xa6\x01\x9f\xef\x90\x93\xa2\x01\x80\x93\xa3\x01\xee\x24\xff\x24\xf6\xce\x88\x23\x09\xf4"
"\x14\xcf\x80\x91\x9c\x01\x88\x23\x09\xf0\x0f\xcf\x20\x92\x9c\x01\x5a\xd6\x80\x91\xd0\x01\x90\xe0\x82\x30\x91\x05\xac\xf0"
"\x40\xe0\x50\xe0\x00\x00\x4f\x5f\x5f\x4f\x80\x91\xd0\x01\x90\xe0\x01\x97\x6c\xeb\x72\xe0\x86\x9f\x90\x01\x87\x9f\x30\x0d"
"\x96\x9f\x30\x0d\x11\x24\x42\x17\x53\x07\x6c\xf3\x82\xe3\x90\xe0\xea\xd6\x20\xe9\x31\xe0\xf8\x94\xd1\xba\xc8\xba\x78\x94"
"\x8c\xe3\x90\xe0\x00\x00\x01\x97\xe9\xf7\x18\xba\x8c\xe8\x90\xe0\x00\x00\x01\x97\xe9\xf7\x21\x50\x30\x40\x71\xf7\x20\xe9"
"\x31\xe0\xf8\x94\xd1\xba\x98\xba\x78\x94\x8c\xe3\x90\xe0\x00\x00\x01\x97\xe9\xf7\x18\xba\x8c\xe8\x90\xe0\x00\x00\x01\x97"
"\xe9\xf7\x21\x50\x30\x40\x71\xf7\x03\xd6\xc4\xce\x20\x92\x9b\x01\x0f\xd6\x20\x91\xd0\x01\x30\xe0\x21\x50\x30\x40\xec\xeb";
#elif BLOCK_NUMBER == 7
/* -------------------- 7 -------------------- */
"\xf2\xe0\x2e\x9f\xc0\x01\x2f\x9f\x90\x0d\x3e\x9f\x90\x0d\x11\x24\x01\x97\x00\x00\x01\x97\xe9\xf7\x82\xe3\x90\xe0\xa8\xd6"
"\x27\xee\x33\xe0\x80\xe0\x2b\x83\x3c\x83\xf5\xd7\xb7\xd7\x2b\x81\x3c\x81\x21\x50\x30\x40\xb1\xf7\x27\xee\x33\xe0\x81\xe0"
"\x2b\x83\x3c\x83\xe9\xd7\xab\xd7\x2b\x81\x3c\x81\x21\x50\x30\x40\xb1\xf7\xd1\xd5\x92\xce\x80\xe0\xe0\xd4\xc9\xce\x80\xe0"
"\x0e\xcf\x42\xe0\x40\x93\x68\x02\x20\x92\xa2\x01\x51\xe8\x50\x93\xa3\x01\x64\xe0\x60\x93\x30\x02\x80\x91\x4e\x02\x86\x95"
"\x86\x95\x81\x70\x80\x93\x2a\x02\xaa\x24\xbb\x24\x66\x24\x77\x24\xee\x24\xff\x24\x80\x91\x30\x02\x83\x30\x09\xf4\x1c\xcf"
"\x80\x91\x30\x02\x84\x30\x09\xf0\x4a\xce\x38\xef\x23\x2e\x08\xb6\x00\xfe\xfd\xcf\x22\xbe\x88\xb7\x81\x60\x88\xbf\xfb\xd7"
"\xc7\x01\x83\x70\x90\x70\x00\x97\x61\xf5\x60\x91\xa8\x01\x70\x91\xa9\x01\x80\x91\x3c\x02\x90\x91\x3d\x02\x68\x9f\x50\x01"
"\x69\x9f\xb0\x0c\x78\x9f\xb0\x0c\x11\x24\x80\x91\xa6\x01\x90\x91\xa7\x01\xa8\x1a\xb9\x0a\x80\x91\x36\x02\x90\x91\x37\x02"
"\xa8\x0e\xb9\x1e\xc5\x01\x0c\xdc\x3c\x01\x39\xd6\xc7\x01\x8f\x70\x90\x70\x00\x97\x69\xf0\x08\x94\xe1\x1c\xf1\x1c\x80\x91"
"\x30\x02\x84\x30\x41\xf2\x0f\xce\x72\xda\xc5\x01\xb3\x01\x68\xdb\xf3\xcf\x33\xdb\xc3\x01\xa9\xdd\x21\xe0\xe2\x2e\xf1\x2c"
"\xef\xcf\x53\x02\xc0\x01\x42\x9f\xb0\x01\x52\x03\x70\x0d\x81\x1d\x11\x24\x91\x1d\x34\x03\x70\x0d\x81\x1d\x11\x24\x91\x1d"
"\x08\x95\x62\x9f\xd0\x01\x73\x9f\xf0\x01\x82\x9f\xe0\x0d\xf1\x1d\x64\x9f\xe0\x0d\xf1\x1d\x92\x9f\xf0\x0d\x83\x9f\xf0\x0d"
"\x74\x9f\xf0\x0d\x65\x9f\xf0\x0d\x99\x27\x72\x9f\xb0\x0d\xe1\x1d\xf9\x1f\x63\x9f\xb0\x0d\xe1\x1d\xf9\x1f\xbd\x01\xcf\x01"
"\x11\x24\x08\x95\xaa\x1b\xbb\x1b\x51\xe1\x07\xc0\xaa\x1f\xbb\x1f\xa6\x17\xb7\x07\x10\xf0\xa6\x1b\xb7\x0b\x88\x1f\x99\x1f"
"\x5a\x95\xa9\xf7\x80\x95\x90\x95\xbc\x01\xcd\x01\x08\x95\xa1\xe2\x1a\x2e\xaa\x1b\xbb\x1b\xfd\x01\x0d\xc0\xaa\x1f\xbb\x1f"
"\xee\x1f\xff\x1f\xa2\x17\xb3\x07\xe4\x07\xf5\x07\x20\xf0\xa2\x1b\xb3\x0b\xe4\x0b\xf5\x0b\x66\x1f\x77\x1f\x88\x1f\x99\x1f"
"\x1a\x94\x69\xf7\x60\x95\x70\x95\x80\x95\x90\x95\x9b\x01\xac\x01\xbd\x01\xcf\x01\x08\x95\x97\xfb\x09\x2e\x05\x26\x0e\xd0"
"\x57\xfd\x04\xd0\xd7\xdf\x0a\xd0\x00\x1c\x38\xf4\x50\x95\x40\x95\x30\x95\x21\x95\x3f\x4f\x4f\x4f\x5f\x4f\x08\x95\xf6\xf7"
"\x90\x95\x80\x95\x70\x95\x61\x95\x7f\x4f\x8f\x4f\x9f\x4f\x08\x95\xdc\x01\xcb\x01\xfc\x01\xe1\x99\xfe\xcf\x06\xc0\xff\xbb"
"\xee\xbb\xe0\x9a\x31\x96\x0d\xb2\x0d\x92\x41\x50\x50\x40\xb8\xf7\x08\x95\xf8\x94\xff\xcf\x00\x00\x10\xa4\xe2\x04\x01\x00"
"\x08\x45\x07\x00\x32\x00\x66\x00\x66\x00\x99\x00\x64\x00\x4c\x04\x0a\x00\x09\x00\x0b\x00\xe8\x03\x0a\x00\x00\x00\x00\x08"
"\xe8\x03\xec\x13\x05\x00\x00\x00\x80\x00\x00\x00\x01\x01\x10\xa4\xe2\x04\x01\x00\x08\x45\x07\x00\x32\x00\x26\x00\x26\x00"
"\x33\x00\x64\x00\x4c\x04\x0a\x00\x08\x00\x0b\x00\xf4\x01\x03\x00\x64\x00\x00\x10\xe8\x03\x50\x14\x07\x00\x00\x00\x80\x00"
"\x00\x00\x02\x01\x10\xa4\xe2\x04\x01\x00\x08\x45\x07\x00\x32\x00\xcc\x00\xcc\x00\x32\x01\x64\x00\x4c\x04\x0a\x00\x0a\x00"
"\x07\x00\xe8\x03\x0a\x00\x00\x00\x00\x08\x84\x03\x50\x14\x08\x00\x00\x00\x1e\x00\x14\x00\x02\x02\x10\xa4\xe2\x04\x01\x00"
"\x08\x45\x07\x00\x32\x00\xcc\x00\xcc\x00\x32\x01\x64\x00\x4c\x04\x0a\x00\x0a\x00\x07\x00\xe8\x03\x0a\x00\x00\x00\x00\x08"
"\x84\x03\x50\x14\x08\x00\x00\x00\x1e\x00\x14\x00\x03\x00\xe0\x2e\xb8\x0b\x06\x00\x01\x01\x10\x00\x5a\x00\x1e\x00\x1e\x00"
"\x1e\x00\x78\x00\xb8\x0b\x28\x00\x08\x00\x13\x00\x20\x00\x01\x00\x00\x00\x00\x08\xe8\x03\x20\x4e\x14\x00\x00\x00\x64\x00"
"\x04\x00\x03\x01\x98\x3a\xb0\x04\x08\x00\x01\x01\x07\x00\x32\x00\x26\x00\x26\x00\x19\x00\x64\x00\x4c\x04\x0a\x00\x08\x00"
"\x00\x00\x58\x02\x05\x00\x00\x01\x00\x20\x0a\x00\x98\x3a\x05\x00\x00\x00\x64\x00\x04\x00\x01\x2b\x00\x00\x00\x00\x00\x00";
#elif BLOCK_NUMBER == 8
/* -------------------- 8 -------------------- */
"\x00\x00\x00\x1e\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
#endif


SHA256 sha256;
Hash *hasher = &sha256;
int OFFSET = 30*30*BLOCK_NUMBER;

I2C_eeprom eeprom(0x50, 32768/8);


void setup() {
  start();
  Serial.println("");
  Serial.print("[-] Initialisation de la mémoire EEPROM...\n");
  init_eeprom();
  Serial.print("[-] Ecriture du firmware \n");
  write_firmware();
  Serial.print("[-] Ecriture terminé \n");
  Serial.print("[-] Lecture du firmware \n");
  read_firmware();
  Serial.print("[-] Lecture terminé \n");

}

void loop() {}

void start()
{
  Serial.begin(115200,SERIAL_8N1);
}

void pause()
{
  Serial.end();
  pinMode(1, INPUT);
}

void send_data(unsigned int data)
{
  Serial.print("\\x");
  if (data < 16) Serial.print("0");
  Serial.print(data,HEX);
}


void init_eeprom()
{
    Wire.begin();
    eeprom.begin();
}

void write_firmware()
{
    if (READ_ONLY)
      return;
    if (RESET_MEMORY)
      eeprom.setBlock(0,0xff,8192);
    for (int i = 0; i < 30; i++) {
      int start_pos = i*30;
      int end_pos = (i+1)*30;
      for (int c = start_pos; c<end_pos; c++)
      {
        //send_data(firmware_code[c]);
        eeprom.writeByte(OFFSET+c, firmware_code[c]);
        delay(5);
      }
  }
}

void read_firmware()
{
    hasher->reset();
    for (int i = 0; i < 123; i++) {
      int start_pos = i*64;
      int end_pos = (i+1)*64;
      for (int c = start_pos; c<end_pos; c++)
      {
        
        int data = eeprom.readByte(c);
        if (c < DATA_LENGTH)
          hasher->update(&data,(size_t) 1);
        send_data(data);
        //delay(100);
      }
    Serial.println();
  }

  Serial.print("[-] Hash: ");
  uint8_t hash[HASH_SIZE];
  hasher->finalize(hash, HASH_SIZE);
  for (byte i=0; i < HASH_SIZE; i++)
  {
    if (hash[i]<0x10) { Serial.print('0'); }
    Serial.print(hash[i],HEX);
  }
  Serial.println();
}

Je vérifie que le contenue du firmware sur la EEPROM est en comparant son condensat avec celui du fichier binaire grâce au moniteur en série.

Je réalise maintenant le code Arduino pour flash le firmware de la mémoire EEPROM vers la motorboard.

#include <I2C_eeprom.h>
#include <Wire.h>


bool DEBUG = false;
I2C_eeprom eeprom(0x50, 32768/8);

void setup() {
  // init EEPROM
  init_eeprom();

  delay(1000);
  // init BLC
  pinMode(4, INPUT);
  pinMode(8, OUTPUT);
  blc_resetIRQ();
  delay(5000);
  blc_init();

  delay(5000);
  // send firmware
  send_firmware();
  
}

void loop() {

}

/*--------------- EEPROM ----------------*/
void init_eeprom()
{
    Wire.begin();
    eeprom.begin();
}

void send_firmware()
{
    blc_send(0x61);
    delay(50);
    for (int i = 0; i < 120; i++) {
      int start_pos = i*64;
      int end_pos = (i+1)*64;
      blc_send(0x71);
      delay(100);
      for (int c = start_pos; c<end_pos; c++)
      {
        
        int data = eeprom.readByte(c);
        blc_send(data);
        delay(50);
      }
  }
}

/*--------------- BLC ----------------*/
void start()
{
  Serial.begin(115200,SERIAL_8N1);
}

void pause()
{
  Serial.end();
  pinMode(1, INPUT);
}

void blc_send(int data)
{
  start();
  Serial.write(data);
  pause();
}

void blc_init()
{

  // Initialisation multicast
  blc_reset();
  delay(100);
  
  blc_getVersion();
  delay(100);

  delay(1000);
}


void blc_reset()
{
  blc_send(0xE0);
}

void blc_getVersion()
{
  blc_send(0x91);
}

void blc_resetIRQ()
{
     if (digitalRead(4) == HIGH) {
      pinMode(8, OUTPUT);
      digitalWrite(8, LOW);
      delay(500);
      pinMode(8, INPUT);
   }
}

On est bon, c’est parti pour l’upload.

Après envoie de la commande 0x91, on obtient un checksum différent de 0xC0, ce qui signifie qu’on a bien réussi à uploader quelque chose. Seulement, après l’envoie de 0xA1, on obtient 0xA0 mais la LED s’éteint et plus rien ne répond.

Je pense que la commande 0xA1 lance le code qu’on a flash sur la carte, et qu’il doit y avoir une erreur dans celui-ci, ce qui fait que la motorboard crash. On peut donc supposer que la mémoire de l’atmega8a est organisé comme la capture de gauche.

Pour être totalement transparent c’était une phase du projet un peu compliqué. La deadline se rapprochait très (très) vite et il nous fallait obligatoirement un moteur fonctionnel pour pouvoir passer à l’étape suivante. J’ai opté pour la facilité et j’ai acheté un drone AR DRONE 2 (à 20€) sur Leboncoin afin de récupérer une motorboard. Après vérification du bon fonctionnement de la motorboard, on l’intègre sur le drone et on passe à l’étape suivante: faire marcher les moteurs à l’unisson.

Le démultiplexeur

Le problème est que le protocole BLC des motorboards a deux modes : un mode unicast où les commandes doivent être envoyé à chaque moteur séparément et un mode broadcast où les commandes sont envoyées à tous les moteurs. Comme on ne peut pas réaliser une liaison UART pour chaque moteur, on opte pour l’utilisation d’un démultiplexeur.

Un démultiplexeur, souvent abrégé en « démux », est un dispositif électronique ou un circuit logique utilisé pour envoyer un signal unique vers l’une des nombreuses lignes de sortie. Il peut être considéré comme l’inverse d’un multiplexeur (ou « mux »), qui combine plusieurs signaux d’entrée en un seul signal de sortie.

ChatGPT

Au départ on voulait récupérer les valeurs renvoyées par les motorboards en plus d’envoyer les commandes, c’est pourquoi on a voulu utiliser un multiplexeur analogique, le CD4052, qui permet la circulation du signal dans les deux sens. Le problème est que (visiblement) celui-ci déformait le signal, ce qui le rendait inutilisable (temps de régime transitoire). En effet, on observait une augmentation de la tension à l’état bas (normalement 0V) qui était aux alentours des 3V due à la résistance de […].

On abandonne l’idée de récupérer le retour des commandes des motorboards et on opte pour un composant décodeur/démultiplexeur numérique, le 74HCT139, qui ne devrait pas déformer le signal. On rajoute également quelques diodes afin d’empêcher le retour des commandes moteurs d’arriver dans les broches de sorties du démultiplexeur.

On modifie ensuite le code de l’Arduino pour qu’il assigne à chaque moteur un ID (entre 1 et 4) et ensuite envoyer une vitesse constante. Pour cela, on utilise deux nouveaux PINs (le 2 et le 7) qu’on paramètre en tant que sortie et on les connecte sur les broches A et B du 74HCT139. Ces deux pins codent en binaire le numéro de la sortie à activer.

void setup() {
  
  pinMode(4, INPUT);
  pinMode(8, OUTPUT);

  pinMode(7, OUTPUT);
  pinMode(2, OUTPUT);
  digitalWrite(7, HIGH);
  digitalWrite(2, HIGH);

  
  blc_resetIRQ();
  delay(1000);
  blc_init();

}

void loop() {
  run_motor();
  //delay(50);
}

void start()
{
  Serial.begin(115200,SERIAL_8N1);
}

void pause()
{
  Serial.end();
  pinMode(1, INPUT);
}
void blc_init()
{

  for (int motor_id = 0; motor_id < 4; motor_id+= 1)
  {
      delay(800);
      // Selection du moteur
      int A = (motor_id & 1);
      int B = (motor_id >> 1) & 1;
      if (A == 1)
        digitalWrite(7, HIGH);
      else
        digitalWrite(7, LOW);
      if (B == 1)
        digitalWrite(2, HIGH);
      else
        digitalWrite(2, LOW);
    
      // Initialisation multicast
      start();
      blc_reset();
      pause();
      delay(100);
      
      start();
      blc_getVersion();
      pause();
      delay(100);
      
      start();
      blc_run_motor();
      pause();
      delay(100);
    
      // Initialisation moteur
      start();
      Serial.write(motor_id+1);
      pause();
      delay(100);
      
      start();
      Serial.write(0x40);
      pause();
      delay(100);
    
      delay(1000);
    
      blc_startled();
    
      delay(1000);
      run_motor();
      //blc_stopled();
    
      start();
      blc_reset();
      pause();
      delay(100);
  }
}

void blc_run_motor()
{
  Serial.write(0xA1);
}

void blc_reset()
{
  Serial.write(0xE0);
}

void blc_getVersion()
{
  Serial.write(0x91);
}



void blc_startled()
{
  start();
  Serial.write(0x60);
  pause();
  delay(100);

  start();
  Serial.write(0x1e);
  pause();
  delay(100);
    
}

void blc_stopled()
{
  start();
  Serial.write(0x60);
  pause();
  delay(100);

  start();
  Serial.write(0x00);
  pause();
  delay(100);
    
}

void blc_multicast()
{
  for (int i = 1; i <= 6; i++) {
  start();
  Serial.write(0xa0);
  pause();
  delay(100);
  }
}

void blc_resetIRQ()
{
     if (digitalRead(4) == HIGH) {
      pinMode(8, OUTPUT);
      digitalWrite(8, LOW);
      delay(500);
      pinMode(8, INPUT);
   }
}

void run_motor()
{
    for (int motor_id = 0; motor_id < 4; motor_id+= 1)
    {
      //delay(10);
      // Selection du moteur
      int A = (motor_id & 1);
      int B = (motor_id >> 1) & 1;
      if (A == 1)
        digitalWrite(7, HIGH);
      else
        digitalWrite(7, LOW);
      if (B == 1)
        digitalWrite(2, HIGH);
      else
        digitalWrite(2, LOW);

        
      start();
      Serial.write(35);
      pause();
      delay(5);
    
        start();
      Serial.write(255);
      pause();
      delay(5);
    
        start();
      Serial.write(255);
      pause();
      delay(5);
    
        start();
      Serial.write(255);
      pause();
      delay(5);
    
      start();
      Serial.write(255);
      pause();
      delay(5);
    }
}

On lance le tout et on croise les doigts.
NB: On a ajouté une nouvelle breadboards, la vert, sur la queue du drone. C’est sur cette breadboard qu’on a placé le démultiplexeur.

Et c’est un nouveau succès, les moteurs tourne tous et le drone commence à décoller ! On réécrit le programme sur STM32, en le fusionnant avec celui qui récupère les données des capteurs (accéléromètre et distance). Comme le signal UART délivré par le STM32 a pour tension de niveau logique haut 3.3V, on doit réaliser un petit circuit additionnel : un « Logic Level Shifting Basics ». Ce circuit éleve la tension 3.3 au 5V.

On peut maintenant tester :

Tout est ok, les 4 moteurs tournent (◕‿◕). Maintenant il faut le faire voler…

Les 3 problèmes

Pour connaitre la vitesse qui fait voler notre drone, on fait une boucle dans laquelle on augmente toutes les 50ms la vitesse de 1 jusqu’à atteindre son maximum (2**9-1=511). On y va progressivement, d’abord de 1 à 400, puis de 1 à 511. Sur le deuxième essai, c’est le drame. Les moteurs crash, puis plus rien ne marche (même en utilisant nos codes précédents censés être fonctionnels). En interceptant la sortie des moteurs à l’aide de la sonde logique, on s’aperçoit qu’on a supprimé le firmware du tout les moteurs (le même problème qu’on a rencontré sur notre moteur de test ヾ( •́д•̀ ;)ノ ). C’est le premier problème. Heureusement il y a une solution, maintenant qu’on a un deuxième drone avec une carte mère Parrot fonctionnelle. Comme on l’a vu dans le précédant article, la carte mère check l’intégrité du firmware sur les motorboards et flash le firmware qu’elle a en mémoire si celui n’est pas valide. On alimente donc la carte mère du deuxième drone en (11V) en coinçant deux câbles dans la connectique de la batterie, puis on connecte les moteurs dessus. On rebranche ensuite les moteurs sur notre drone, et on relance notre script et tout remarche (ouf).

Vient maintenant le deuxième problème. On remarque que les moteurs ne tournent pas à une vitesse suffisante pour permettre au drone de voler. On remarque aussi que si l’on envoie une vitesse sur un seul des moteurs il tourne beaucoup plus vite. C’est un problème de courant. Lorsqu’on utilise un seul des 4 moteurs, la consommation de courant est de 2,5 A, ce qui signifie qu’un moteur consomme probablement un courant d’environ 2 A. Or on ne fournit au total que 3 A (le maximum), ce qui n’est pas suffisant. On se munit donc d’un générateur de tension pouvant délivrer des courants plus importants, ce qui règle le souci.

Enfin le troisième et dernier des problèmes : Comme on peut le voir sur la vidéo, seule une partie du drone vole (la partie arrière), l’autre reste cloué au sol. C’est dû au fait que les moteurs ne tournent pas dans le bon sens sur l’avant, ce qui génère une force en direction du sol (on le remarque en essayant de tirer le drone vers le haut). On règle le problème en inversant la position des 2 moteurs et puis :

Victoire !

Il ne nous reste plus qu’à asservir le système à l’aide des capteurs et d’un PID, ce que je présente dans mon prochain post.

———————————————–