Présentation
Le projet NinPi est né en 2012 à la suite de la parution de la revue Open Silicium n°5 et plus particulièrement l'article "Développez vos jeux 'Maison' pour Nintendo DS sous GNU/Linux" à la page 69.
Après avoir acheté cette revue, je l'ai régulièrement consulté sans idée de projet mais en sachant que j'aurais un jour la possibilité de la mettre en pratique.
Aujourd'hui je passe à l'action.
Créer un jeu c'est possible, mais est ce qu'il est possible de faire communiquer la DS avec l'extérieur via le wifi ?
Objectif
Donner la possibilité à toute personne qui dispose d'une carte Raspberry Pi, d'une dongle wifi, d'une Nintendo DS et d'un linker de mettre tout ça en relation.
En effet, certains passionnés en robotique sont toujours à la recherche d'une télécommande
Cette étude est purement théorique, car il faudrait disposer d'un linker (ou carte R4) ce qui est actuellement illégal en France.
Niveau de difficulté
Je suis un gros débutant en langage C en python et encore plus dans le monde du linux et j'y suis arrivé à le faire alors... suivez le guide.
A la date de la rédaction de ce tutoriel j'ai 5 jours de langage C et 3 mois de python.
Les différents liens sont tous repris à la fin du tutoriel.
Pour finir, j'ai rédigé ce tutoriel uniquement pour Linux mais il est possible de le faire sous Windows, sauf coté Raspberry.
Coté PC
Etape 1 - l'installation des logiciels
Dans un navigateur internet, il faut rechercher "devkitpro" et vous avez différentes solutions en Français [1] ou en Anglais [2].
Mon PC est sous Ubuntu et j'ai choisi... le [2].
Donc j'ai repris les étapes du sites mais à ma sauce car refaire l'installation 5 fois de suite permet de prendre certaines légèretés avec ce qui est proposé sur le web.
Dans un Terminal
sudo mkdir -p /opt/devkitrpoJ'ai oublié de préciser qu'il faudra faire tout ça avec les privilèges de root. Donc, maintenant nous avons un répertoire /opt/devkitrpo tout frais pour accueillir le projet.
Il faut modifier les droits d'accès à cet emplacement avec :
sudo chmod 777 /opt/devkitproAvant de télécharger les fichiers nous allons finir l’arborescence.
sudo mkdir /opt/devkitrpo/libnds sudo mkdir /opt/devkitrpo/examplesVous pouvez fermer la console pour l'instant.
Sur le site Web lien[2] vous avez la forme de l'arborescence à venir. Chaque nom de dossier étant un lien hypertexte, je vous invite a télécharger les fichiers :
Au moment de choisir le devkitARM du lien[4] (ci-dessous) je me suis posé la question "est ce que je suis en 64 ou 32 bits ?"
Nouvelle recherche sur le web avec le critère "linux processeur 32 ou 64 bits",. Il est proposé entre autre un site en Français [3]. Je suis en 64 bits.
Pour ma part j'ai donc pris :
[4] devkitARM_r45-x86_64-linux.tar.bz2
[5] libnds-1.5.12.tar.bz2
[6] libfat-nds-1.0.14.tar.bz2
[7] dswifi-0.3.17.tar.bz2
[8] maxmod-nds-1.0.9.tar.bz2
[9] libfilesystem-0.9.12.tar.bz2
[10] default_arm7-0.6.0.tar.bz2
[11] nds-examples-20140401.tar.bz2
C'est fini, j'ai donc tous les fichiers ci-dessus dans "Téléchargements"
Retour dans un Terminal sous les privilèges de root.
Se déplacer dans le répertoire "Téléchargements" qui vient d'accueillir les fichiers qui ont été téléchargés.
cd TéléchargementsIl faut distribuer les fichiers au bon endroit :
sudo cp devkitARM_r45-x86_64-linux.tar.bz2 /opt/devkitpro sudo cp libnds-1.5.12.tar.bz2 /opt/devkitpro/libnds sudo cp libfat-nds-1.0.14.tar.bz2 /opt/devkitpro/libnds sudo cp dswifi-0.3.17.tar.bz2 /opt/devkitpro/libnds sudo cp maxmod-nds-1.0.9.tar.bz2 /opt/devkitpro/libnds sudo cp libfilesystem-0.9.12.tar.bz2 /opt/devkitpro/libnds sudo cp default_arm7-0.6.0.tar.bz2 /opt/devkitpro/libnds sudo cp nds-examples-20140401.tar.bz2 /opt/devkitpro/examplesLes fichiers sont à décompresser :
cd /opt/devkitpro sudo tar -xjf devkitARM_r45-x86_64-linux.tar.bz2Petite vérification avec un "ls" , il doit y avoir un dossier devkitARM qui est arrivé.
Il faut poursuivre avec :
cd /opt/devkitpro/libnds sudo tar -xjf libnds-1.5.12.tar.bz2 sudo tar -xjf libfat-nds-1.0.14.tar.bz2 sudo tar -xjf dswifi-0.3.17.tar.bz2 sudo tar -xjf maxmod-nds-1.0.9.tar.bz2 sudo tar -xjf libfilesystem-0.9.12.tar.bz2 sudo tar -xjf default_arm7-0.6.0.tar.bz2Par chance il y a des exemples pour commencer à s'amuser.
cd /opt/devkitpro/examples sudo tar -xjf nds-examples-20140401.tar.bz2Histoire de conclure l'installation et toujours avec les privilèges de root.
sudo nano /home/A la fin du document il faut coller/.bashrc
export DEVKITPRO=/opt/devkitpro export DEVKITARM=$DEVKITPRO/devkitARMEt maintenant comment vous dire que c'est fini... tout simplement en faisant un test.
Petit redémarrage de l'ordinateur, on ne sais jamais.
Toujours dans un Terminal mais sans changer de privilège :
cd /opt/devkitpro/examples/hello_worldlancer un make pour créer le fichier
makeSi pour vous c'est ok, vous avez de la chance car de mon coté GRRRR ! c'est quoi ce message d'erreur ?
XXXXXXX@XXXXXXXXXXX:/opt/devkitpro/examples/nds/hello_world$ make
main.cpp
arm-eabi-g++ -MMD -MP -MF /opt/devkitpro/examples/nds/hello_world/build/main.d -g -Wall -O2 -march=armv5te -mtune=arm946e-s -fomit-frame-pointer -ffast-math -mthumb -mthumb-interwork -I/opt/devkitpro/examples/nds/hello_world/include -I/opt/devkitpro/examples/nds/hello_world/build -I/opt/devkitpro/libnds/include -I/opt/devkitpro/libnds/include -I/opt/devkitpro/examples/nds/hello_world/build -DARM9 -fno-rtti -fno-exceptions -c /opt/devkitpro/examples/nds/hello_world/source/main.cpp -o main.o
/opt/devkitpro/devkitARM/bin/arm-eabi-g++: 1: Syntax error: "(" unexpected
make[1]: *** [main.o] Error 2
make: *** [build] Error 2
XXXXXXX@XXXXXXXXXXX:/opt/devkitpro/examples/nds/hello_world$
Bon en cherchant sur la toile je suis tombé sur [12] qui semble expliquer, qu'il faut changer le fichier devkitARM.J'ai téléchargé un nouveau devkitARM.
[4] devkitARM_r45-i686-linux.tar.bz2
Dans un Terminal c'est du déjà vue :
cd Téléchargements sudo cp devkitARM_r45-i686-linux.tar.bz2 /opt/devkitpro cd /opt/devkitproIl faut supprimer le répertoire devkitARM existant ainsi que ses sous répertoires et fichiers
sudo rm -Rf devkitARM sudo tar -xjf devkitARM_r45-i686-linux.tar.bz2Nouveau test
cd /opt/devkitpro/examples/hello_world makeCA MARCHE
J'ai bien un fichier hello_world.nds ainsi qu'un dossier « build » qui a servi lors de la construction du fichier final.
L'émulateur
Un émulateur est une application servant à visualiser un jeu (de DS ou autre). Il vous servira beaucoup pour tester vos jeux, c'est plus pratique que de prendre chaque fois sa DS. Sauf que les émulateurs ne gèrent pas / gèrent mal les fichiers et le Wifi.
Sinon il faut avoir une connaissance qui à un ami qui à ...
Coté Raspberry Pi
Etape 2 - Préparation de la Raspberry
Laissons de coté les fichiers nds pour nous pencher sur la préparation de la Raspberry.
Ce tutoriel n'a pas pour objectif de vous faire un projet complet mais bien de vous présenter une méthode.
2-1 installation de A à Z :
1) formatage avec l'image 2015-02-16-raspbian-wheezy.img
2) dans raspi-config
- expand Filesystem
- enable camera -> enable
- advance option
- SSH -> enable
3) passage du clavier de qwerty en azerty
sudo nano /etc/default/keyboardremplacement de gb par fr
4) redémarrage
sudo reboot5) mise à jour
sudo apt-get update && sudo apt-get upgrade -yAvec les cinq premières étapes vous avez une carte Raspberry en état de fonctionner mais pour notre projet il faut poursuivre avec la création d'une borne wifi. [14] et [15] mais j'ai changé les adresses ip en fonction de mon réseau,
6) paramétrage d'une adresse static
sudo nano /etc/network/interfaces
auto lo iface lo inet loopback iface eth0 inet static address 192.168.0.65 #adresse de la carte raspberry en filaire netmask 255.255.255.0 gateway 192.168.0.254 #adresse de la FreeBox allow-hotplug wlan0 iface wlan0 inet static address 192.168.100.1 #adresse de la carte raspberry en wifi netmask 255.255.255.07) nouvelle mise à jour
sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade && sudo apt-get -y autoremove8) installation du serveur dhcp et de hostapd qui va créer le point wifi
sudo apt-get install hostapd isc-dhcp-server -y9) modification du fichier dhcpd.conf
sudo nano /etc/dhcp/dhcpd.confCommenter les deux lignes suivantes :
option domain-name "example.org"; option domain-name-servers ns1.example.org, ns2.example.org;donc elles deviennent
#option domain-name "example.org"; #option domain-name-servers ns1.example.org, ns2.example.org;Toujours dans le même fichier dé-commenter la ligne
#authoritative;après
authoritative;et pour finir en fin de fichier coller ce qui suit :
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.10 192.168.100.50;
option broadcast-address 192.168.100.255;
option routers 192.168.100.1;
default-lease-time 600;
max-lease-time 7200;
};
La partie ci-dessus indique dans la première ligne « subnet » l'adrsse du serveur qui alloue les adresses IP. La deuxième lignes « range » indique la plage des adresses possible donc entre 192.168.100.10 et 192.168.100.50.
les deux dernières lignes précisent le temps de réservation d'une adresse IP pour une machine.9) indication du port utilisée pour la création du wifis
sudo nano /etc/default/isc-dhcp-serverRechercher la ligne
INTERFACES=""pour indiquer wlan0
INTERFACES="wlan0"A ce stade le serveur dchp fonctionne, il faut maintenant créer la borne wifi
10) modification de hostapd.conf pour correspondre à nos besoins
sudo nano /etc/hostapd/hostapd.conf
ctrl_interface=/var/run/hostapd ############################### # Basic Config ############################### macaddr_acl=0 auth_algs=1 # Most modern wireless drivers in the kernel need driver=nl80211 driver=rtl871xdrv ########################## # Local configuration... ########################## interface=wlan0 bridge=br0 ssid=RaspberryPI_AP hw_mode=g ieee80211n=1 channel=1 auth_algs=1 wmm_enabled=0En ce qui me concerne j'avais un problème avec la ligne du driver qui sur une grande partie des tutos est driver=nl80211 alors que pour moi c'est driver=rtl871xdrv
11) indiquer à hostpad l'emplacement de son fichier de conf
sudo nano /etc/default/hostapdRemplacer la ligne
#DAEMON_CONF=""par
DAEMON_CONF="/etc/hostapd/hostapd.conf"12) la même modification mais ailleurs
sudo nano /etc/init.d/hospapdRemplacer également la ligne
#DAEMON_CONF=""par
DAEMON_CONF="/etc/hostapd/hostapd.conf"13) Préciser le type d'IP
sudo nano /etc/sysctl.confen fin de document coller :
net.ipv4.ip_forward=114)
sudo sh -c "echo 1>/proc/sys/net/ipv4/ip_forward"15) mise à jour du driver pour accepter le « rtl871xdrv »
wget http://adafruit-download.s3.amazonaws.com/adafruit_hostapd_14128.zip unzip adafruit_hostapd_14128.zip sudo mv /usr/sbin/hostapd /usr/sbin/hostapd.ORIG sudo mv hostapd /usr/sbin sudo chmod 755 /usr/sbin/hostapdLancer au démarrage du nano ordinateur les deux services
sudo update-rc.d hostapd enable sudo update-rc.d isc-dhcp-server enableSur un smartphone, il doit y avoir un wifi libre (sans clé WEP ou WAP) au nom de RaspberryPI_AP quivient d'apparaître.
Une nintendo DS ne supporte pas le wap elle accepte uniquement le wep d'ou la création de cette borne sans sécurité.
Je sais que coté sécurité ce n'est pas bien, il faudra régler ça un jour...
2-2 premier test
Sur le PC, dans un Terminal se connecter en ssh à la Raspberry
Il faut (dans mon cas) ouvrir deux consoles terminal l'une à coté de l'autre afin d'avoir sur l'une la connexion en ssh avec la raspberry(terminal 1) et l'autre pour passer des commandes en local (terminal 2)
terminal 1 :
ssh pi@<192.168.0.65>L'adresse IP est dans mon cas imposée par le point 6) ci-dessus et le mot de passe est raspberry si vous n'avez rien changé.
Création d'un dossier ninpi pour le projet
terminal 1 :
mkdir ninpiterminal 1 :
cd ninpiterminal 1 :
sudo nano /home/pi/ninpi/test_led.pycopier/coller le code
terminal 1 :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Une LED branchée à la pin 18 clignote
import RPi.GPIO as GPIO # bibliothèque pour utiliser les GPIO
import time # bibliothèque pour gestion du temps
GPIO.setmode(GPIO.BCM) # mode de numérotation des pins
GPIO.setup(18,GPIO.OUT) # la pin 18 réglée en sortie (output)
GPIO.setup(23,GPIO.OUT) # la pin 18 réglée en sortie (output)
while True: # boucle répétée jusqu'à l'interruption du programme
GPIO.output(18,GPIO.HIGH) # sortie au niveau logique haut (3.3 V)
GPIO.output(23,GPIO.LOW) # sortie au niveau logique bas (0 V)
time.sleep(1) # on ne change rien pendant 1 seconde
GPIO.output(18,GPIO.LOW) # sortie au niveau logique bas (0 V)
GPIO.output(23,GPIO.HIGH) # sortie au niveau logique bas (0 V)
time.sleep(1) # on ne change rien pendant 1 seconde
Fermer et enregistrer
Sur la Plaque d'essai il faut [16] placer la led et la résistance sur le GPIO18,Toujours en SSH
terminal 1 :
sudo python /home/pi/ninpi/test_led.pyC'est l'habituel clignotement de led
Pour arrêter
terminal 1 -> ctrl+c
2-3 travail sur les sockets
Il est possible de demander à un programme de surveiller des ports afin que deux ordinateurs distants ou deux programmes sur une même machine puissent communiquer [17] et [18].
C'est exactement ce dont nous avons besoin.
Nouveau programme
terminal 1 :
sudo nano /home/pi/ninpi/test_socket.pyterminal 1 :
#!/usr/bin/env python
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
s.close()
Fermer et enregistrerToujours avec la raspberry en SSH
terminal 1 :
sudo python /home/pi/ninpi/server.py Socket created Socket bind complete Socket now listeningOuvrir un deuxième terminal sur le pc et placer les deux fenêtres de terminal l'une à coté de l'autre pour voir les échanges.
Changement de terminal
terminal 2 :
telnet <192.168.0.65> 8888sur la fenêtre terminal SSH de la raspberry doit apparaître une nouvelle ligne.
terminal 1 :
sudo python /home/pi/ninpi/server.py Socket created Socket bind complete Socket now listening Connected with 127.0.0.1:47758Attention il faut sortir proprement sinon il faudra changer le port d'écoute à chaque clôture du programme.
Pour sortir de telnet
terminal 2 : ctrl+altgr+]
terminal 2 -> ctrl+z
Puis
terminal 1 -> ctrl+c
2-2 utilisation des sockets et GPIO
Pour rendre plus attractif le projet j'ai rajouté une deuxième led avec sa résistance sur le GPIO 23 (borne 16)
Petite fusion des deux scripts python pour allumer l'une ou l'autre des leds en fonction des demandes. Le Programme ninpi.py va attendre quatre commandes possible via les lettres a,b,c ou d
terminal 1 :
sudo nano /home/pi/ninpi/ninpi.pyterminal 1 :
#!/usr/bin/env python
# coding: utf-8
import socket
import sys
import RPi.GPIO as GPIO # bibliothèque pour utiliser les GPIO
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 5555 # Arbitrary non-privileged port
GPIO.setmode(GPIO.BCM) # mode de numérotation des pins
GPIO.setup(18,GPIO.OUT) # la pin 18 réglée en sortie (output)
GPIO.setup(23,GPIO.OUT) # la pin 18 réglée en sortie (output)
GPIO.setwarnings(False)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
while 1:
#Receiving from client
data = conn.recv(2048)
print 'data '+data
if data == "a":
GPIO.output(23,GPIO.HIGH) # sortie au niveau logique haut (3.3 V)
elif data == "b":
GPIO.output(23,GPIO.LOW) # sortie au niveau logique haut (3.3 V)
else:
break
s.close()
GPIO.cleanup()
Je n'ai jamais réussi à faire clignoter les leds depuis un appel telnet car il y a l'encodage UTF-8 à respecter.Il faut faut donc passer par un programme client.py
terminal 1 :
sudo nano /home/pi/ninpi/client.pyterminal 1 :
#!/usr/bin/env python
# coding: utf-8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("", 8888))
file_name = raw_input(">> ") # utilisez raw_input() pour les anciennes versions python
s.send(file_name.encode())
Il faut passer les deux consoles terminal sur la raspberryterminal 2 :
ssh pi@<162.168.0.65>Encore le mot de passe raspberry
terminal 1 :
sudo python /home/pi/ninpi/ninpi.py Socket created Socket bind complete Socket now listening Connected with 127.0.0.1:47758terminal 2 :
sudo python /home/pi/ninpi/ninpi.pyJe vous laisse jouer et fermer les programmes.
Etape 3 – Test du Wifi avec les fichier nds
Il faut ramener le terminal 2 sur le pc.
terminal 2 :
exitPour faire communiquer le programme nds avec la raspberry, nous allons utiliser le wifi. Comme par hasard dans les exemples il y en a trois justement qui traite de cette partie.
terminal 2 :
cd /opt/devkitrpo/examples/dswifi/autoconnectterminal 2 :
makeLà, encore une fois, si votre ami qui est illégal avec son linker a de la chance :
Simple Wifi Connection Demo Connecting via WFC Data ... Connected ip : xxx.xxx.xxx.xxx gateway: xxx.xxx.xxx.xxx mask : xxx.xxx.xxx.xxx dns1 : xxx.xxx.xxx.xxx dns2 : xxx.xxx.xxx.xxxSinon
Simple Wifi Connection Demo Connecting via WFC Data ... Failed to connect!Bon c'est vraiment un parcours du combattant cette histoire.
Nouvelle recherche sur le net avec les mots cléfs : WFC_connect devkitpro failed
Après une lecture d'une quinzaine de site, apparaît que le devkitpro ne supporte pas le chiffrement WPA. Son mode de sécurité est le WEP non le WPA.
Donc retour sur
terminal 2 :
cd /opt/devkitrpo/examples/dswifi/ap_searchterminal 2 :
makeRécupérer le fichier nds pour scanner les réseaux wifi qui sont a proximité
Etape 4 – Le projet NinPi global
Petit rappel de l'objectif de ce tutoriel : pouvoir faire clignoter une led sur la raspberry en fonction du bouton utilisé sur la Nintendo.
Création du répertoire ninpi pour accueillir les fichiers et dossier indispensable à la création du ninpi.nds
Dernière recherche sur le net concernant les sockets et le langage c [19]
terminal 2 :
sudo mkdir -p /opt/devkitrpo/ninpiterminal 2 :
sudo mv /opt/devkitpro/examples/dswifi/httpget /opt/devkitrpo/ninpipour renommer le fichier
terminal 2 :
sudo mv /opt/devkitrpo/ninpi/source/httpget.c /opt/devkitrpo/ninpi/source/ninpi.cterminal 2 :
sudo nano /opt/devkitrpo/ninpi/source/ninpi.cModifier le code comme suit :
terminal 2 :
#includeterminal 2 :#include #include #include #include #include #include #include //DECLARATION DE LA FONCTION QUI SERA UTILISEE APRES //POUR EVITER UNE ERREUR DE COMPILATION void getHttp(char* request, int my_socket); //--------------------------------------------------------------------------------- Wifi_AccessPoint* findAP(void){ //--------------------------------------------------------------------------------- int selected = 0; int i; int count = 0, displaytop = 0; static Wifi_AccessPoint ap; Wifi_ScanMode(); //this allows us to search for APs int pressed = 0; do { scanKeys(); //find out how many APs there are in the area count = Wifi_GetNumAP(); consoleClear(); iprintf("%d APs detected\n\n", count); int displayend = displaytop + 10; if (displayend > count) displayend = count; //display the APs to the user for(i = displaytop; i < displayend; i++) { Wifi_AccessPoint ap; Wifi_GetAPData(i, &ap); // display the name of the AP iprintf("%s %.29s\n Wep:%s Sig:%i\n", i == selected ? "*" : " ", ap.ssid, ap.flags & WFLAG_APDATA_WEP ? "Yes " : "No ", ap.rssi * 100 / 0xD0); } pressed = keysDown(); //move the selection asterick if(pressed & KEY_UP) { selected--; if(selected < 0) { selected = 0; } if(selected = count) { selected = count - 1; } displaytop = selected - 9; if (displaytop<0) displaytop = 0; } swiWaitForVBlank(); } while(!(pressed & KEY_A)); //user has made a choice so grab the ap and return it Wifi_GetAPData(selected, &ap); return ≈ } //--------------------------------------------------------------------------------- void keyPressed(int c){ //--------------------------------------------------------------------------------- if(c > 0) iprintf("%c",c); } //--------------------------------------------------------------------------------- int main(void) { //--------------------------------------------------------------------------------- Wifi_InitDefault(false); consoleDemoInit(); Keyboard* kb = keyboardDemoInit(); kb->OnKeyPressed = keyPressed; while(1) { int status = ASSOCSTATUS_DISCONNECTED; consoleClear(); consoleSetWindow(NULL, 0,0,32,24); Wifi_AccessPoint* ap = findAP(); consoleClear(); consoleSetWindow(NULL, 0,0,32,24); iprintf("Connecting to %s\n", ap->ssid); //this tells the wifi lib to use dhcp for everything Wifi_SetIP(0,0,0,0,0); char wepkey[64]; int wepmode = WEPMODE_NONE; if (ap->flags & WFLAG_APDATA_WEP) { iprintf("Enter Wep Key\n"); while (wepmode == WEPMODE_NONE) { scanf("%s",wepkey); if (strlen(wepkey)==13) { wepmode = WEPMODE_128BIT; } else if (strlen(wepkey) == 5) { wepmode = WEPMODE_40BIT; } else { iprintf("Invalid key!\n"); } } Wifi_ConnectAP(ap, wepmode, 0, (u8*)wepkey); } else { Wifi_ConnectAP(ap, WEPMODE_NONE, 0, 0); } consoleClear(); while(status != ASSOCSTATUS_ASSOCIATED && status != ASSOCSTATUS_CANNOTCONNECT) { status = Wifi_AssocStatus(); int len = strlen(ASSOCSTATUS_STRINGS[status]); iprintf("\x1b[0;0H\x1b[K"); iprintf("\x1b[0;%dH%s", (32-len)/2,ASSOCSTATUS_STRINGS[status]); scanKeys(); if(keysDown() & KEY_B) break; swiWaitForVBlank(); } if(status == ASSOCSTATUS_ASSOCIATED) { u32 ip = Wifi_GetIP(); //AFFICHAGE ADRESSE IP iprintf("\nip: [%i.%i.%i.%i]\n", (ip ) & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF); // Find the IP address of the server, with gethostbyname struct hostent * myhost = gethostbyname( "192.168.100.1" ); iprintf("Found IP Address!\n"); // Create a TCP socket int my_socket; my_socket = socket( AF_INET, SOCK_STREAM, 0 ); iprintf("Created Socket!\n"); // Tell the socket to connect to the IP address we found, on port 80 (HTTP) struct sockaddr_in sain; sain.sin_family = AF_INET; sain.sin_port = htons(5555); sain.sin_addr.s_addr= *( (unsigned long *)(myhost->h_addr_list[0]) ); connect( my_socket,(struct sockaddr *)&sain, sizeof(sain) ); iprintf("Connected to server!\n"); while(1) { //TOUT VA BIEN, BOUCLE INFINI char * request; scanKeys(); int pressed = keysDown(); // SI BOUTTON A if(pressed&KEY_A) { getHttp("a",my_socket); } // SI BOUTTON B if(pressed&KEY_B) { getHttp("b",my_socket); } if(pressed&KEY_X) { getHttp("x",my_socket); } // SI BOUTTON B if(pressed&KEY_Y) { getHttp("y",my_socket); } //RAFRAICHISSEMNT ECRAN consoleClear(); swiWaitForVBlank(); } } else { iprintf("\nConnection failed!\n"); } } iprintf("Other side closed connection!"); int my_socket; // good practice to shutdown the socket. shutdown(my_socket,0); // remove the socket. closesocket(my_socket); return 0; } //--------------------------------------------------------------------------------- void getHttp(char* request, int my_socket) { //--------------------------------------------------------------------------------- // send our request send( my_socket, request, strlen(request), 0 ); iprintf("Sent our request : %c \n",request ); // Print incoming data iprintf("Printing incoming data:\n"); // int recvd_len; // char incoming_buffer[256]; //while( ( recvd_len = recv( my_socket, incoming_buffer, 255, 0 ) ) != 0 ) { // if recv returns 0, the socket has been closed. // if(recvd_len>0) { // data was received! // incoming_buffer[recvd_len] = 0; // null-terminate // iprintf(incoming_buffer); // } //} }
cd /opt/devkitrpo/ninpi/terminal 2 :
makeRécupérer le fichier ninpi.nds pour le mettre dans… l'émulateur !!!
Sur la raspberry
terminal 1 :
sudo nano /home/pi/ninpi/ninpi.pyterminal 1 :
#!/usr/bin/env python
# coding: utf-8
import socket
import sys
import RPi.GPIO as GPIO # bibliothèque pour utiliser les GPIO
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 5555 # Arbitrary non-privileged port
GPIO.setmode(GPIO.BCM) # mode de numérotation des pins
GPIO.setup(18,GPIO.OUT) # la pin 18 réglée en sortie (output)
GPIO.setup(23,GPIO.OUT) # la pin 18 réglée en sortie (output)
GPIO.setwarnings(False)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
while 1:
#Receiving from client
data = conn.recv(2048)
print 'data '+data
if data == "a":
GPIO.output(18,GPIO.HIGH) # sortie au niveau logique haut (3.3 V)
elif data == "b":
GPIO.output(18,GPIO.LOW) # sortie au niveau logique haut (3.3 V)
elif data == "x":
GPIO.output(23,GPIO.HIGH) # sortie au niveau logique haut (3.3 V)
elif data == "y":
GPIO.output(23,GPIO.LOW) # sortie au niveau logique haut (3.3 V)
else:
break
reply = 'OK pour ' + data
conn.sendall(reply)
s.close()
GPIO.cleanup()
terminal 1 :sudo python /ninpi/ninpi.pyConclusion :
Vous l'aurez compris, il n'y a pas une installation simplifiée et idéale. En vous indiquant mes déboires et mes questionnements, j'espère vous avoir guidé sur la piste de votre configuration.
Je vais donc maintenant ouvrir un projet de robot : le NinPiBot
Liens externes :
[1] https://openclassrooms.com/courses/programmez-sur-votre-nintendo-ds
[2] http://devkitpro.org/wiki/Getting_Started/devkitARM
[3] http://lea-linux.org/documentations/Trucs:Savoir_processeur_64_bits_ou_32_bits
[4] https://sourceforge.net/projects/devkitpro/files/devkitARM/devkitARM_r45/
[5] https://sourceforge.net/projects/devkitpro/files/libnds/1.5.12/
[6] https://sourceforge.net/projects/devkitpro/files/libfat/1.0.14/
[7] https://sourceforge.net/projects/devkitpro/files/dswifi/0.3.17/
[8] https://sourceforge.net/projects/devkitpro/files/maxmod/
[9] https://sourceforge.net/projects/devkitpro/files/filesystem/0.9.12/
[10] https://sourceforge.net/projects/devkitpro/files/default%20arm7/0.6.0/
[11] https://sourceforge.net/projects/devkitpro/files/examples/nds/
[12] https://devkitpro.org/viewtopic.php?f=2&t=2391
[13] http://blog.idleman.fr/tutoriel-02-brancher-et-installer-le-raspberry-pi/
[14] https://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/install-software
[15] http://www.instructables.com/id/How-to-make-a-WiFi-Access-Point-out-of-a-Raspberry/
[16] http://www.geekland-leblog.fr/faire-clignote-une-led-en-python/
[17] http://apprendre-python.com/page-reseaux-sockets-python-port
[18] http://www.binarytides.com/python-socket-server-code-example/
[19] https://www.debian-fr.org/t/socket-en-c-client-serveur-tout-simple/3448