MrYsLab / s2a_fm

A Scratch Hardware Extension For Arduino
GNU General Public License v3.0
104 stars 64 forks source link

s2a_fm.bat enhancement #8

Closed davecraig closed 10 years ago

davecraig commented 10 years ago

Firstly, many thanks for s2a_fm. I'm about to start using it as a first step in robotics for some 10 years olds. A few issues cropped up in my preparation which I thought I'd share and you can incorporate if you wish.

The Arduino's have USB serial numbers which mean that they enumerate on unique COM ports on windows. To aid startup I needed a batch file which finds the right COM port and passes it in to s2a_fm. Batch files really aren't my thing, but here's what I've done:

for /f "tokens=4 delims=: " %%A in ('mode ^| findstr "COM[0-9]*:"') do c:\python27\python.exe s2a_fm.py %%A

This strips the colon from the first COM port found and passes it in to s2a_fm. It works for me because I've no built in COM ports. If you know of a better way, including it in the extra goodies would be great.

SebCanet commented 10 years ago

Hi, thanks a lot for your job, that's a great idea. I'm sorry I cannot help...only trying :-D Your script works well, but my Arduino Uno is on COM3, so it takes time to scan...and each Arduino card keeps its COM port so on my other PC sometimes a card is on COM27... And with my Arduino Mega on COM4 it crashed :

Opening Arduino Serial port COM4 Please wait while Arduino is being detected. This can take up to 30 seconds ... Exception in thread Thread-2: Traceback (most recent call last): File "c:\python2\lib\threading.py", line 810, in __bootstrap_inner self.run() File "c:\python2\lib\site-packages\PyMata\pymata_command_handler.py", line 729 , in run method(command_data) File "c:\python2\lib\site-packages\PyMata\pymata_command_handler.py", line 368 , in analog_message = (data[self.MSB] << 7) + data[self.LSB] IndexError: list index out of range

Board Auto Discovery Failed!, Shutting Down Traceback (most recent call last): File "s2a_fm.py", line 144, in s2a_fm() File "s2a_fm.py", line 79, in s2a_fm firmata.analog_mapping_query() File "c:\python2\lib\site-packages\PyMata\pymata.py", line 190, in analog_mapp ing_query self._command_handler.send_sysex(self._command_handler.ANALOG_MAPPING_QUERY, None) File "c:\python2\lib\site-packages\PyMata\pymata_command_handler.py", line 532 , in send_sysex self.pymata.transport.write(data) File "c:\python2\lib\site-packages\PyMata\pymata_serial.py", line 100, in writ e self.arduino.write(data) File "c:\python2\lib\site-packages\serial\serialwin32.py", line 279, in write if not self.hComPort: raise portNotOpenError serial.serialutil.SerialException: Attempting to use a port that is not openpy %%A

I know that students working on project auto-detect Arduino board by scanning if the UUID exists.

Thanks for your help, Sebastien

Le 23/08/2014 13:48, davecraig a écrit :

Firstly, many thanks for s2a_fm. I'm about to start using it as a first step in robotics for some 10 years olds. A few issues cropped up in my preparation which I thought I'd share and you can incorporate if you wish.

The Arduino's have USB serial numbers which mean that they enumerate on unique COM ports on windows. To aid startup I needed a batch file which finds the right COM port and passes it in to s2a_fm. Batch files really aren't my thing, but here's what I've done:

for /f "tokens=4 delims=: " %%A in ('mode ^| findstr "COM[0-9]*:"') do c:\python27\python.exe s2a_fm.py %%A

This strips the colon from the first COM port found and passes it in to s2a_fm. It works for me because I've no built in COM ports. If you know of a better way, including it in the extra goodies would be great.

— Reply to this email directly or view it on GitHub https://github.com/MrYsLab/s2a_fm/issues/8.

MrYsLab commented 10 years ago

Thanks for the suggestion. I looked at auto-port detection a while ago, but found it to be unreliable (my implementation of it). I will revisit this and if I am successful in coming up with a reliable solution, I will incorporate it into the next release.

SebCanet commented 10 years ago

Le 23/08/2014 16:01, Alan Yorinks a écrit :

Thanks for the suggestion. I looked at auto-port detection a while ago, but found it to be unreliable (my implementation of it). I will revisit this and if I am successful in coming up with a reliable solution, I will incorporate it into the next release.

— Reply to this email directly or view it on GitHub https://github.com/MrYsLab/s2a_fm/issues/8#issuecomment-53153651.

This is a copy of the program, sorry the comment are in French.... It's from our project :https://code.google.com/p/openorganigram/ https://code.google.com/p/openorganigram/

void Arduino::Detecter() //Arduino detection { QextSerialEnumerator Enumerateur ; //L'objet Enumerateur mentionnant tous les ports séries QList ListePortsCOM = Enumerateur.getPorts() ; //on met ces informations dans une liste

 //on parcourt la liste des ports

 bool bArduinoPresent(false) 

; //Booléen à true si l'Arduino est présent QString sNomPortCOM ("") ; //sNom va permettre de récuperer le nom du port (EX:COM7) for(signed register int i=0; i < ListePortsCOM.length(); i++) //On parcours la totalité des ports séries détectés { //FONCTIONNEL WINDOWS ET LINUX !!!! if(ListePortsCOM[i].vendorID == 0x2341) //Si parmi tous les ports, un port avec leVID à 2341 alors l'Arduino est détecté { bArduinoPresent = true ; //On met le booléen à true pour indiquer que l'Arduino est là sNomPortCOM = ListePortsCOM[i].portName ; //sNom est complété par le numéro de port de l'Arduino } }

 if(bArduinoPresent) //Si l'Arduino est présent
 {
     //qDebug() << "Arduino Détecté" ;                            

//On affiche un message indiquant sa détection if(this->PortSerie == 0)
//Si le port est nul { this->Connecter(sNomPortCOM) ;
//On lance la connexion avec le numéro de port } else { this->DureeDeConnexion = this->DureeDeConnexion.addMSecs(10) ; //On incrémente le compteur de 10 ms

if(!this->PortSerie->isOpen()) //Si le port n'est pas ouvert { this->PortSerie->open(QextSerialPort::ReadWrite) ; //On l'ouvre en lecture et écriture } } } else {

     //qDebug() << "Arduino Non Détecté" ;                        

//Message indiquant que l'Arduino est non détecté this->Deconnecter() ;
//On lance la déconnexion }

 emit Signal_Temps(this->DureeDeConnexion) ;                      

//On émet le signal qui va permettre d'incrémenter le compteur de temps de connexion de l'Arduino }

/\ Elle permet de connecter l'Arduino en l'initialisant selon les règles du port série

void Arduino::UtiliserArduino() { this->bArduinoUtilisable = true; }

/* Elle permet de Deconnecter l'Arduino et de remettre à zéro le compteur **/ void Arduino::Deconnecter() { emit ArduinoConnect(DECONNECTE, "") ; //On émet que l'Arduino est déconnecté

 this->DureeDeConnexion.setHMS(0, 0, 0, 0) 

; //On met le compteur à zéro

 if(this->PortSerie != 0) //Si le port série n'est pas nul(Fermé, 

utilisé dans une autre application par exemple) { //qDebug() << "Deconnexion" ; //On affiche que l'on va le déconnecter this->PortSerie->close() ; //On ferme le port disconnect(this->PortSerie, SIGNAL(readyRead()), this, SLOT(RecevoirDonnees())) ; //On déconnecte les signaux précédents delete this->PortSerie ; //On supprime le port }

 this->bArduinoUtilisable = 

false; //On dit que l'Arduino n'est pas utilisable

 this->PortSerie = 0 ; //On initialise le port à 0

}

/* Elle permet d'émettre l'état de l'Arduino **/ void Arduino::DemanderEtat() { if(this->PortSerie == 0) //Si le port est nul { emit ArduinoConnect(DECONNECTE, "") ; //On envoie le signal indiquant qu'il est déconnecté } else { if(this->PortSerie->isOpen() && this->bArduinoUtilisable) //Si le port est ouvert et utilisable { emit ArduinoConnect(CONNECTE, this->PortSerie->portName()) ; //On envoie le signal indiquant qu'il est connecté ainsi que son numéro de port } else { emit ArduinoConnect(PORT_FERME, this->PortSerie->portName()) ; //On envoie le signal indiquant que le port est fermé ainsi que son numéro de port } } }

MrYsLab commented 10 years ago

Thanks for the code, and the comments in French are not a problem. I am using the pyserial library and was unable to come up with a reliable cross platform (linux, windows, and mac) solution for port autodetection. I will revisit it again, and if I am successful, I will incorporate the solution in the next release.

SebCanet commented 10 years ago

Le 23/08/2014 17:00, Alan Yorinks a écrit :

Thanks for the code, and the comments in French are not a problem. I am using the pyserial library and was unable to come up with a reliable cross platform (linux, windows, and mac) solution for port autodetection. I will revisit it again, and if I am successful, I will incorporate the solution in the next release.

— Reply to this email directly or view it on GitHub https://github.com/MrYsLab/s2a_fm/issues/8#issuecomment-53155262.

They coded with Qt Designer. I'm not a programming specialist (just I can read and understand) and I cannot help you, sorry. But with my little capacities I made some minor modification on the s2a_fm.bat, because I'm also trainer for French STEM teacher and they a lot of difficulties with little things like that...and I would like it to be the easiest possible for kids. @echo off break ON cls echo Vous devez verifier la derniere ligne de ce fichier afin qu'elle corresponde echo au numero de port de la carte Arduino : dans le gestionnaire de peripheriques, echo quel port COM lui est attribue ? echo. echo Mais aussi lui indiquer dans quel dossier vous avez installe Python. echo. echo IMPORTANT : ce fichier doit etre execute depuis le dossier de s2a_fm, echo la ou se trouve le fichier s2a_fm.py echo Vous pouvez par contre en creer un raccourci pour etre execute depuis le bureau. echo. c:\python2\python s2a_fm.py com3

MrYsLab commented 10 years ago

I totally agree that it would be a nice feature, so if I can, I will include it in the next release.