├── ArduinoFiles └── README.TXT ├── README.md ├── ScratchFiles ├── ExtensionDescriptors │ ├── P4K_Extension.s2e │ ├── s2a_fm.s2e │ ├── s2a_fm_DE.s2e │ ├── s2a_fm_Es.s2e │ ├── s2a_fm_Fr.s2e │ ├── s2a_fm_GR.s2e │ ├── s2a_fm_It.s2e │ ├── s2a_fm_NL.s2e │ ├── s2a_fm_Pt.s2e │ ├── s2a_fm_ja.s2e │ ├── s2a_fm_ja2.s2e │ ├── s2a_fm_ko.s2e │ ├── s2a_fm_zh_cn.s2e │ └── s2a_fm_zh_tw.s2e └── ScratchProjects │ ├── P4K_Extension.sb2 │ ├── Turn On LED On Pin 6.sb2 │ ├── s2a_fm_base.sb2 │ ├── s2a_fm_base_DE.sb2 │ ├── s2a_fm_base_Es.sb2 │ ├── s2a_fm_base_Fr.sb2 │ ├── s2a_fm_base_GR.sb2 │ ├── s2a_fm_base_It.sb2 │ ├── s2a_fm_base_Pt.sb2 │ ├── s2a_fm_base_ja.sb2 │ ├── s2a_fm_base_ko.sb2 │ ├── s2a_fm_base_nl.sb2 │ ├── s2a_fm_base_zh_cn.sb2 │ ├── s2a_fm_base_zh_tw.sb2 │ ├── sonarTest.sb2 │ └── spinning_cat.sb2 ├── Snap!Files ├── Español │ ├── blink.xml │ ├── blink_tiempo_variable.xml │ ├── boton.xml │ ├── boton_con_imagen.xml │ ├── contador1.xml │ ├── contador2.xml │ ├── s2a_fm_Snap_base_Es.xml │ ├── semaforo_tiempo_variable.xml │ ├── servo1.xml │ └── servo2.xml ├── S2a_fm_Pt.xml ├── Snap!Mobile │ ├── StandardFirmataYun │ │ └── StandardFirmataYun │ │ │ └── StandardFirmataYun.ino │ ├── arduino │ │ ├── PyMata │ │ │ ├── __init__.py │ │ │ ├── pymata.py │ │ │ ├── pymata_command_handler.py │ │ │ └── pymata_serial.py │ │ ├── log │ │ │ └── s2a_fm_debugging.log │ │ ├── s2a_fm.py │ │ ├── scratch_command_handlers.py │ │ ├── scratch_http_server.py │ │ ├── serial │ │ │ ├── __init__.py │ │ │ ├── rfc2217.py │ │ │ ├── serialcli.py │ │ │ ├── serialjava.py │ │ │ ├── serialposix.py │ │ │ ├── serialutil.py │ │ │ ├── serialwin32.py │ │ │ ├── sermsdos.py │ │ │ ├── tools │ │ │ │ ├── __init__.py │ │ │ │ ├── list_ports.py │ │ │ │ ├── list_ports_linux.py │ │ │ │ ├── list_ports_osx.py │ │ │ │ ├── list_ports_posix.py │ │ │ │ ├── list_ports_windows.py │ │ │ │ └── miniterm.py │ │ │ ├── urlhandler │ │ │ │ ├── __init__.py │ │ │ │ ├── protocol_hwgrep.py │ │ │ │ ├── protocol_loop.py │ │ │ │ ├── protocol_rfc2217.py │ │ │ │ └── protocol_socket.py │ │ │ └── win32.py │ │ └── xlate.cfg │ └── wiredMotorTest.xml ├── Turn On LED On Pin 6.xml ├── blink.xml ├── s2a_fm_Snap_base.xml ├── s2a_fm_Snap_base_DE.xml ├── s2a_fm_Snap_base_Es.xml ├── s2a_fm_Snap_base_FR.xml ├── s2a_fm_Snap_base_GR.xml ├── s2a_fm_Snap_base_It.xml ├── s2a_fm_Snap_base_dutch.xml ├── s2a_fm_Snap_base_ko.xml ├── s2a_fm_Snap_base_zh_cn.xml ├── s2a_fm_Snap_base_zh_tw.xml └── spinning_sprite.xml ├── documentation ├── Español │ └── s2a_fm_Espanish_tutorial.pdf ├── LED_EXAMPLE.png ├── pot1.png ├── s2a_fm_reference - 完成稿.pdf ├── s2a_fm_reference.pdf ├── s2a_fm_參考文件.pdf ├── scratch_blocks.png ├── scratch_langs.png └── snap_blocks.png ├── extra_goodies ├── linux │ └── s2a_fm.sh └── windows │ └── s2a_fm.bat ├── license.txt ├── s2a_fm.py ├── scratch_command_handlers.py ├── scratch_http_server.py └── xlate.cfg /ArduinoFiles/README.TXT: -------------------------------------------------------------------------------- 1 | All custom Arduino Firmata sketches may be found in PyMata @ https://github.com/MrYsLab/PyMata 2 | 3 | You can also use StandardFirmata supplied with the Arduino IDE, if you do not need the extended features of the custom 4 | sketches. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | s2a_fm 2 | ====== 3 | 4 | [![Join the chat at https://gitter.im/MrYsLab/s2a_fm](https://badges.gitter.im/MrYsLab/s2a_fm.svg)](https://gitter.im/MrYsLab/s2a_fm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 |

6 | Sublime's custom image 7 |

8 | 9 | # A New Version For Python 3.5, called s2aio, Is Available [Here](https://github.com/MrYsLab/s2aio/wiki). 10 | 11 | Arduino users! Would you like to configure and control your Arduino micro-controller without having 12 | to write a single line of Arduino sketch code and at the same time have access to a graphical user 13 | interface? 14 | 15 | Scratch and Snap! programmers! Would you like to control and communicate with an Arduino board using 16 | Scratch? Imagine, using Scratch to control physical devices such as LEDs, motors, and relays while 17 | monitoring devices, such as temperature sensors, potentiometers, and light sensors. What would you 18 | create? 19 | 20 | Want to do motor control using Snap! and Wifi? Check out our article on Physical Computing. 21 | http://www.instructables.com/id/The-SnapMobile-Start-Your-Physical-Computing-Engin/ 22 | 23 | All the code is included here! 24 | 25 | s2a_fm is a Scratch/Snap! hardware extension written in Python allowing Scratch or Snap! and an Arduino 26 | micro-controller to communicate seamlessly. 27 | 28 | Program Block translations are included for Chinese, Dutch, English (default), French, German, Greek, Italian, Korean, Portuguese, Spanish, and Taiwanese. 29 | 30 | Make sure you get the latest version of the Scratch Off-Line editor if you are using Scratch (version 404 or greater). 31 | 32 | Check Out Our Blog 33 | ------------------ 34 | http://mryslab.blogspot.com/ 35 | 36 | Installation Instructions 37 | -------------------------- 38 | The s2a_fm Reference Manual, s2a_fm_reference.pdf, located in the documentation directory of this distribution, 39 | provides full installation instructions. 40 | 41 | Alternative Japanese Block Translation May 30, 2017 42 | -------------------------------------- 43 | Translations provided through the generosity of Hiroaki Kawashima 44 | 45 | Japanese Block Translation Oct 17 2016 46 | -------------------------------------- 47 | Translations provided through the generosity of Antoine Choppin 48 | 49 | Greek Block Translation Feb 3, 2015 50 | ----------------------------------- 51 | Translations provided through the generosity of Alexandros Moskofidis 52 | 53 | Italian Block Translation Dec 12, 2014 54 | --------------------------------------- 55 | Translations provided through the generosity of Gianfranco Zuliani 56 | 57 | New Language Translation October 9, 2014 58 | ------------------------ 59 | Taiwanese translation provided through the courtesy of Hsu Jen-Chieh. 60 | 61 | Version 1.5 Apr 12, 2014 62 | ------------------------ 63 | New Features for 1.5 64 | 65 | Korean translation provided through the generosity of Dr. Eungil Kim 66 | 67 | Portuguese and German translations of Block Text provided through the generosity of 68 | Aldo von Wangenheim, from www.computacaonaescola.ufsc.br 69 | 70 | A Chinese translation of the reference manual was graciously provided by Yufangjun 发自我的小米手机 71 | 72 | Version 1.4 Mar 23, 2014 73 | ----------------------- 74 | New Feature for 1.4 75 | 76 | Chinese translation of Block Text provided through the generosity of Professor YuFangjun 77 | 78 | French translation of Block Text provided through the generosity of Professor Sebastien Canet 79 | . 80 | 81 | Version 1.3 Feb 23, 2014 82 | ------------------------ 83 | New Features for 1.3 84 | 85 | 1. Support for the upcoming Snap!Mobile Physical Computing Project in "Instructables" 86 | 87 | 2. Spanish Translation of Block Text and a Spanish Tutorial provided courtesy of Professor 88 | José Manuel Ruiz 89 | 90 | 91 | Version 1.2 Jan 1, 2014 92 | ----------------------- 93 | New Features for 1.2: 94 | 95 | 1. Support for Snap! 4.0 provided. 96 | 97 | 2. Support for up to 4 simultaneous HC-SR04 type "Ping" Sensors. 98 | (This requires using PyMata version 1.54 or greater and the FirmataPlus Arduino sketch supplied with PyMata 1.54). 99 | 100 | 3. Dutch translation for the Scratch/Snap! Block Text included (Thanks to Sjoerd Dirk Meijer). 101 | 102 | 4. Provision to translate Scratch/Snap! Block Text to any language. 103 | 104 | Version 1.1 December 19, 2013 105 | ----------------------------- 106 | 107 | New Features for 1.1: 108 | 109 | 1. When enabling a digital pin, the pin capabilty is verified for the requested mode. 110 | 111 | 2. A new Scratch debugger command block has been added to help debug Scratch scripts. 112 | 113 | Known Snap! 4.0 Extension Issues 114 | ---------------------- 115 | None. 116 | 117 | 118 | Known Scratch 2.0 Extension Issues 119 | ------------ 120 | All previous major issues have been resolved as of version 404 of the Off-Line editor. 121 | 122 | None. 123 | 124 | Scratch s2a_fm Extension Blocks 125 | ------------------------------- 126 | 127 | ![ScreenShot](https://raw.github.com/MrYsLab/s2a_fm/master/documentation/scratch_blocks.png) 128 | 129 | Snap! s2a_fm Extension Blocks 130 | ----------------------------- 131 | ![ScreenShot](https://raw.github.com/MrYsLab/s2a_fm/master/documentation/snap_blocks.png) 132 | 133 | Wiring Diagrams for Examples 134 | ---------------------------- 135 | 136 | ![ScreenShot](https://raw.github.com/MrYsLab/s2a_fm/master/documentation/LED_EXAMPLE.png) 137 | 138 | ![ScreenShot](https://raw.github.com/MrYsLab/s2a_fm/master/documentation/pot1.png) 139 | 140 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/P4K_Extension.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "P4K Extension", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/s2a_fm", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state Digital Pin %n for %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Enable", 11 | "PIN", 12 | "Input" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state Analog Pin (A) %n for Input", 17 | "analog_pin_mode", 18 | "Enable", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "DigitalWrite Set Pin %n to %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "AnalogWrite (PWM) Set Pin %n to %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Play Tone on Pin: %n HZ: %n ms: %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Turn Tone Off for Pin: %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Move Servo on Pin %n Deg: %n", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Read Digital Pin %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Read Analog Pin (A) %n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Debugger %m.off_on", 71 | "debugger", 72 | "Off" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Enable", 78 | "Disable" 79 | ], 80 | "digital_pin_mode": [ 81 | "Input", 82 | "Output", 83 | "PWM", 84 | "Servo", 85 | "Tone", 86 | "SONAR" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "Off", 94 | "On" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch to Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state Digital Pin %n for %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Enable", 11 | "PIN", 12 | "Input" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state Analog Pin (A) %n for Input", 17 | "analog_pin_mode", 18 | "Enable", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "DigitalWrite Set Pin %n to %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "AnalogWrite (PWM) Set Pin %n to %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Play Tone on Pin: %n HZ: %n ms: %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Turn Tone Off for Pin: %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Move Servo on Pin %n Deg: %n", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Read Digital Pin %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Read Analog Pin (A) %n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Debugger %m.off_on", 71 | "debugger", 72 | "Off" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Enable", 78 | "Disable" 79 | ], 80 | "digital_pin_mode": [ 81 | "Input", 82 | "Output", 83 | "PWM", 84 | "Servo", 85 | "Tone", 86 | "SONAR" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "Off", 94 | "On" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_DE.s2e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ExtensionDescriptors/s2a_fm_DE.s2e -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_Es.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch para Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state PIN Digital %n como %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Activar", 11 | "PIN", 12 | "Entrada" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state PIN Anal�gico (A) %n como entrada", 17 | "analog_pin_mode", 18 | "Activar", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "Valor Digital en PIN %n poner a %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "Escribir valor Anal�gico(PWM) en Pin %n poner a %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Generar Tono en PIN: %n HZ: %n MS: %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Apagar Tono en PIN: %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Mover Servo en Pin %n Grados: %n", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Leer PIN Digital %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Leer PIN Anal�gico(A) %n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Depurar %m.off_on", 71 | "debugger", 72 | "No" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Activar", 78 | "Desactivar" 79 | ], 80 | "digital_pin_mode": [ 81 | "Entrada", 82 | "Salida", 83 | "PWM", 84 | "Servo", 85 | "Tono", 86 | "SONAR" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "No", 94 | "Si" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_Fr.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "Scratch pour Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state la broche Digital %n comme une %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Activer", 11 | "PIN", 12 | "entrée." 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state la broche Analogique A%n comme une entrée", 17 | "analog_pin_mode", 18 | "Activer", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "Mettre l'état logique de la broche Digital %n à %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "Ecrire sur la broche PWM %n la valeur %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Jouer le son sur la broche %n , fréquence (Hz) : %n , durée (ms) : %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Arrêter le son sur la broche : %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Tourner le servo-moteur sur la broche %n de : %n degrés", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "l'état logique de la broche Digital %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "la valeur sur la broche Analogique A%n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Debugger %m.off_on", 71 | "debugger", 72 | "Arrêt" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Activer", 78 | "Désactiver" 79 | ], 80 | "digital_pin_mode": [ 81 | "entrée.", 82 | "sortie.", 83 | "impulsion PWM.", 84 | "rotation Servo-moteur.", 85 | "sortie Son.", 86 | "mesure Sonar." 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "Arrêt", 94 | "Marche" 95 | ] 96 | } 97 | } -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_GR.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch για το Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state Ψηφιακό PIN %n για %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Ενεργοποίηση", 11 | "PIN", 12 | "Είσοδο" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state Αναλογικό PIN (A) %n για Είσοδο", 17 | "analog_pin_mode", 18 | "Ενεργοποίηση", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "Ψηφιακή Εγγραφή όρισε Pin %n σε %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "Αναλογική Εγγραφή (PWM) όρισε Pin %n σε %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Παίξε τόνο στο Pin: %n HZ: %n για ms: %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Σταμάτησε τόνο στο Pin: %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Μετακίνησε το Σέρβο στο Pin %n κατά μοίρες: %n", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Διάβασε Ψηφιακή Είσοδο στο Pin %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Διάβασε Αναλογική Είσοδο στο Pin (A) %n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Αποσφαλματωτής %m.off_on", 71 | "debugger", 72 | "Κλείσιμο" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Ενεργοποίηση", 78 | "Απενεργοποίηση" 79 | ], 80 | "digital_pin_mode": [ 81 | "Είσοδο", 82 | "Έξοδο", 83 | "PWM", 84 | "Σέρβο", 85 | "Τόνος", 86 | "Σόναρ" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "Κλείσιμο", 94 | "Άνοιγμα" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_It.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch per Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state Pin Digitale %n come %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "Attiva", 11 | "PIN", 12 | "Ingresso" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state Pin Analogico (A) %n come Ingresso", 17 | "analog_pin_mode", 18 | "Attiva", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "Imposta Pin Digitale %n a %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "Imposta Pin Analogico (PWM) %n a %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Esegui Tono su Pin %n Frequenza: %n Hz Durata: %n ms", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Interrompi Tono su Pin %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Sposta Servo su Pin %n Posizione: %n gradi", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Livello Logico Pin Digitale %n", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Valore Pin Analogico (A) %n", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Debugger %m.off_on", 71 | "debugger", 72 | "No" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "Attiva", 78 | "Disattiva" 79 | ], 80 | "digital_pin_mode": [ 81 | "Ingresso", 82 | "Uscita", 83 | "PWM", 84 | "Servo", 85 | "Tono", 86 | "Sonar" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "No", 94 | "Si" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_NL.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch voor Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "Zet %m.pin_state : Digitale pin %n als %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "aan", 11 | "PIN", 12 | "ingang" 13 | ], 14 | [ 15 | " ", 16 | "Zet %m.pin_state : Analoge pin (A) %n als ingang", 17 | "analog_pin_mode", 18 | "aan", 19 | "PIN" 20 | ], 21 | [ 22 | "", 23 | "DigitalWrite: Maak pin %n %m.high_low", 24 | "digital_write", 25 | "PIN", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "AnalogWrite (PWM): Maak pin %n %n", 31 | "analog_write", 32 | "PIN", 33 | "VAL" 34 | ], 35 | [ 36 | "", 37 | "Speel toon op pin %n , Hz: %n , ms: %n", 38 | "play_tone", 39 | "PIN", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "Zet toon uit op pin %n", 46 | "tone_off", 47 | "PIN" 48 | ], 49 | [ 50 | "", 51 | "Draai servo op pin %n %n graden", 52 | "set_servo_position", 53 | "PIN", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "Lees digitale pin %n uit", 59 | "digital_read", 60 | "PIN" 61 | ], 62 | [ 63 | "r", 64 | "Lees analoge pin (A) %n uit", 65 | "analog_read", 66 | "PIN" 67 | ], 68 | [ 69 | "", 70 | "Debugger %m.off_on", 71 | "debugger", 72 | "uitgeschakeld" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "aan", 78 | "uit" 79 | ], 80 | "digital_pin_mode": [ 81 | "ingang", 82 | "uitgang", 83 | "PWM", 84 | "servo", 85 | "toon", 86 | "afstand" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "ingeschakeld", 94 | "uitgeschakeld" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_Pt.s2e: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ExtensionDescriptors/s2a_fm_Pt.s2e -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_ja.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - アルドゥイーノ用スクラッチ", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%n 番目のデジタルピンを %m.digital_pin_mode として %m.pin_state にする", 9 | "digital_pin_mode_ja", 10 | "1", 11 | "入力", 12 | "有効" 13 | ], 14 | [ 15 | " ", 16 | "%n 番目のアナログピンを入力として %m.pin_state にする", 17 | "analog_pin_mode_ja", 18 | "1", 19 | "有効" 20 | ], 21 | [ 22 | "", 23 | "%n 番目のデジタルピンを %m.high_low に設定する", 24 | "digital_write", 25 | "1", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "%n 番目のPWMピンに %n と言う値を書き込む", 31 | "analog_write", 32 | "1", 33 | "10" 34 | ], 35 | [ 36 | "", 37 | "%n 番目のピンに次の音を鳴らす、周波数: %n ハーツ、長さ: %n ミリ秒", 38 | "play_tone", 39 | "1", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "%n 番目のピンで音を止める", 46 | "tone_off", 47 | "1" 48 | ], 49 | [ 50 | "", 51 | "%n 番目のピンのサーボモーターを %n 度で回す", 52 | "set_servo_position", 53 | "1", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "%n 番目のデジタルピンの状態", 59 | "digital_read", 60 | "1" 61 | ], 62 | [ 63 | "r", 64 | "%n 番目のアナログピンの値", 65 | "analog_read", 66 | "1" 67 | ], 68 | [ 69 | "", 70 | "デバッガーを %m.off_on", 71 | "debugger", 72 | "止める" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "有効", 78 | "無効" 79 | ], 80 | "digital_pin_mode": [ 81 | "入力", 82 | "出力", 83 | "PWM波", 84 | "サーボモーターの回転", 85 | "音声出力", 86 | "超音波の距離測定" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "止める", 94 | "動かす" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_ja2.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "デジタルピン %n を %m.digital_pin_mode に %m.pin_state", 9 | "digital_pin_mode_ja", 10 | "1", 11 | "入力", 12 | "使う" 13 | ], 14 | [ 15 | " ", 16 | "アナログピン %n を入力に %m.pin_state", 17 | "analog_pin_mode_ja", 18 | "1", 19 | "使う" 20 | ], 21 | [ 22 | "", 23 | "デジタルピン %n を %m.high_low にする", 24 | "digital_write", 25 | "1", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "PWMピン %n を値 %n にする", 31 | "analog_write", 32 | "1", 33 | "10" 34 | ], 35 | [ 36 | "", 37 | "ピン %n の音を鳴らす: %n Hz, %n ミリ秒", 38 | "play_tone", 39 | "1", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "ピン %n の音を止める", 46 | "tone_off", 47 | "1" 48 | ], 49 | [ 50 | "", 51 | "ピン %n のサーボを %n 度にする", 52 | "set_servo_position", 53 | "1", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "デジタルピン %n の状態", 59 | "digital_read", 60 | "1" 61 | ], 62 | [ 63 | "r", 64 | "アナログピン %n の値", 65 | "analog_read", 66 | "1" 67 | ], 68 | [ 69 | "", 70 | "デバッガーを %m.off_on", 71 | "debugger", 72 | "止める" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "使う", 78 | "使わない" 79 | ], 80 | "digital_pin_mode": [ 81 | "入力", 82 | "出力", 83 | "PWM", 84 | "サーボ", 85 | "音", 86 | "ソナー" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "止める", 94 | "動かす" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_ko.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "스크래치2&아두이노", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state : 디지털 %n 번핀 / %m.digital_pin_mode 모드", 9 | "digital_pin_mode", 10 | "사용", 11 | "0", 12 | "입력" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state : 아날로그 %n 번핀", 17 | "analog_pin_mode", 18 | "사용", 19 | "0" 20 | ], 21 | [ 22 | "", 23 | "디지털 %n 번핀에 %m.high_low 보내기", 24 | "digital_write", 25 | "0", 26 | "0" 27 | ], 28 | [ 29 | "", 30 | "디지털(전류조절) %n 번핀에 %n 보내기", 31 | "analog_write", 32 | "0", 33 | "0" 34 | ], 35 | [ 36 | "", 37 | "신호음 %n 번핀에서 %n 주파수로 %n 동안 재생하기", 38 | "play_tone", 39 | "0", 40 | "HZ", 41 | "ms" 42 | ], 43 | [ 44 | "", 45 | "%n 번핀의 신호음 끄기", 46 | "tone_off", 47 | "0" 48 | ], 49 | [ 50 | "", 51 | "서보모터 %n 번핀을 %n ° 만큼 회전시키기", 52 | "set_servo_position", 53 | "0", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "디지털 %n 번핀 값 읽어오기", 59 | "digital_read", 60 | "0" 61 | ], 62 | [ 63 | "r", 64 | "아날로그 %n 번핀 값 읽어보기", 65 | "analog_read", 66 | "0" 67 | ], 68 | [ 69 | "", 70 | "디버거 %m.off_on", 71 | "debugger", 72 | "끄기" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "사용", 78 | "미사용" 79 | ], 80 | "digital_pin_mode": [ 81 | "입력", 82 | "출력", 83 | "전류조절", 84 | "서보모터", 85 | "신호음", 86 | "음파탐지" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "끄기", 94 | "켜기" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_zh_cn.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch to Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | " 设置 %m.pin_state : 数字引脚 %n 为 %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "允许", 11 | "引脚号", 12 | "输入" 13 | ], 14 | [ 15 | " ", 16 | "设置 %m.pin_state : 模拟引脚(A) %n 为 输入", 17 | "analog_pin_mode", 18 | "允许", 19 | "引脚号" 20 | ], 21 | [ 22 | "", 23 | "数字脚输出: 设置引脚 %n 为 %m.high_low", 24 | "digital_write", 25 | "引脚号", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "模拟输出 (PWM): 设置引脚 %n 的值为 %n", 31 | "analog_write", 32 | "引脚号", 33 | "数量值" 34 | ], 35 | [ 36 | "", 37 | "在引脚 %n 演奏 ,频率为: %n Hz ,时长为 : %n ms", 38 | "play_tone", 39 | "引脚号", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "关闭引脚 %n 的音调", 46 | "tone_off", 47 | "引脚号" 48 | ], 49 | [ 50 | "", 51 | "设置第 %n 脚为舵机输出 转动角度为 %n", 52 | "set_servo_position", 53 | "引脚号", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "读取数字脚 %n 的值", 59 | "digital_read", 60 | "引脚号" 61 | ], 62 | [ 63 | "r", 64 | "读取模拟脚(A) %n 的值", 65 | "analog_read", 66 | "引脚号" 67 | ], 68 | [ 69 | "", 70 | "调试 %m.off_on", 71 | "debugger", 72 | "关" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "允许", 78 | "禁止" 79 | ], 80 | "digital_pin_mode": [ 81 | "输入", 82 | "输出", 83 | "PWM", 84 | "舵机", 85 | "音调", 86 | "超声波" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "关", 94 | "开" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ExtensionDescriptors/s2a_fm_zh_tw.s2e: -------------------------------------------------------------------------------- 1 | { 2 | "extensionName": "s2a_fm - Scratch to Arduino", 3 | "extensionPort": 50209, 4 | "url": "https://github.com/MrYsLab/PyMata", 5 | "blockSpecs": [ 6 | [ 7 | " ", 8 | "%m.pin_state : 數位腳位 %n 為 %m.digital_pin_mode", 9 | "digital_pin_mode", 10 | "啟用", 11 | "號碼", 12 | "輸入" 13 | ], 14 | [ 15 | " ", 16 | "%m.pin_state : 類比腳位(A) %n 為 輸入", 17 | "analog_pin_mode", 18 | "啟用", 19 | "號碼" 20 | ], 21 | [ 22 | "", 23 | "數位輸出: 設定腳位 %n 為 %m.high_low", 24 | "digital_write", 25 | "號碼", 26 | 0 27 | ], 28 | [ 29 | "", 30 | "模擬類比輸出(PWM): 設定腳位 %n 的值為 %n", 31 | "analog_write", 32 | "號碼", 33 | "數量值" 34 | ], 35 | [ 36 | "", 37 | "在腳位 %n 播放音調, 頻率為: %n Hz, 時間為: %n ms", 38 | "play_tone", 39 | "號碼", 40 | 1000, 41 | 500 42 | ], 43 | [ 44 | "", 45 | "關閉腳位 %n 的音調", 46 | "tone_off", 47 | "號碼" 48 | ], 49 | [ 50 | "", 51 | "設定第 %n 腳位為伺服機輸出 轉動角度為 %n", 52 | "set_servo_position", 53 | "號碼", 54 | 90 55 | ], 56 | [ 57 | "r", 58 | "讀取數位腳位 %n 的值", 59 | "digital_read", 60 | "號碼" 61 | ], 62 | [ 63 | "r", 64 | "讀取類比腳位(A) %n 的值", 65 | "analog_read", 66 | "號碼" 67 | ], 68 | [ 69 | "", 70 | "除錯工具 %m.off_on", 71 | "debugger", 72 | "關" 73 | ] 74 | ], 75 | "menus": { 76 | "pin_state": [ 77 | "啟用", 78 | "停用" 79 | ], 80 | "digital_pin_mode": [ 81 | "輸入", 82 | "輸出", 83 | "PWM", 84 | "伺服機", 85 | "音調", 86 | "超音波" 87 | ], 88 | "high_low": [ 89 | "0", 90 | "1" 91 | ], 92 | "off_on": [ 93 | "關", 94 | "開" 95 | ] 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/P4K_Extension.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/P4K_Extension.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/Turn On LED On Pin 6.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/Turn On LED On Pin 6.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_DE.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_DE.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_Es.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_Es.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_Fr.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_Fr.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_GR.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_GR.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_It.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_It.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_Pt.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_Pt.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_ja.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_ja.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_ko.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_ko.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_nl.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_nl.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_zh_cn.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_zh_cn.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/s2a_fm_base_zh_tw.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/s2a_fm_base_zh_tw.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/sonarTest.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/sonarTest.sb2 -------------------------------------------------------------------------------- /ScratchFiles/ScratchProjects/spinning_cat.sb2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/ScratchFiles/ScratchProjects/spinning_cat.sb2 -------------------------------------------------------------------------------- /Snap!Files/Español/blink.xml: -------------------------------------------------------------------------------- 1 | data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4CAYAAAB1ovlvAAABjElEQVR4nO3SsY2DAAAEQXcDERRCQp0EFAWF8NmLxHb0WomfkS6/YF8XhF71Af43AZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZIS4BvjOF7bttU3Hk+AH6zr+rtpmq7jOOpLjyPAL+4R3rcsS33tEQT4hQD/lgA/uAc3z/N1nmd96XEE+MYwDNe+7/WNxxMgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiApAZISICkBkhIgKQGSEiCpH6qOr8jKQ12nAAAAAElFTkSuQmCCdata:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAFoCAYAAACPNyggAAACtUlEQVR4nO3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+Bo3+AAF/RMkcAAAAAElFTkSuQmCC
1datamapmany1data lists
1
1
110i
1
cont
catchtag
cont
catchtag
ActivarActivar 2 | Desactivar5EntradaEntrada 3 | Salida 4 | PWM 5 | Servo 6 | Tono 7 | SONAR
ActivarActivar 8 | Desactivar5
5
5
500 9 | 1
5128
51000500
5
590
NoNo 10 | Si
-------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/PyMata/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/PyMata/pymata_serial.py: -------------------------------------------------------------------------------- 1 | __author__ = 'Copyright (c) 2013 Alan Yorinks All rights reserved.' 2 | """ 3 | Created on Tue Sep 3 07:12:01 2013 4 | 5 | @author: Alan Yorinks 6 | Copyright (c) 2013-14 Alan Yorinks All rights reserved. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public 10 | License as published by the Free Software Foundation; either 11 | version 3 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | """ 22 | 23 | import threading 24 | import serial 25 | 26 | 27 | class PyMataSerial(threading.Thread): 28 | """ 29 | This class manages the serial port for Arduino serial communications 30 | """ 31 | 32 | # class variables 33 | arduino = serial.Serial() 34 | 35 | port_id = "" 36 | baud_rate = 115200 37 | timeout = 1 38 | command_deque = None 39 | 40 | 41 | def __init__(self, port_id, command_deque): 42 | """ 43 | Constructor: 44 | @param command_deque: A reference to the deque shared with the _command_handler 45 | """ 46 | self.port_id = port_id 47 | self.command_deque = command_deque 48 | 49 | threading.Thread.__init__(self) 50 | self.daemon = True 51 | self.arduino = serial.Serial(self.port_id, self.baud_rate, 52 | timeout=int(self.timeout)) 53 | 54 | 55 | def open(self): 56 | """ 57 | open the serial port using the configuration data 58 | returns a reference to this instance 59 | """ 60 | # open a serial port 61 | print '\nOpening Arduino Serial port %s ' % self.port_id 62 | 63 | try: 64 | 65 | # in case the port is already open, let's close it and then 66 | #reopen it 67 | self.arduino.close() 68 | self.arduino.open() 69 | return self.arduino 70 | 71 | except Exception: 72 | # opened failed - will report back to caller 73 | raise 74 | 75 | def close(self): 76 | """ 77 | Close the serial port 78 | return: None 79 | """ 80 | self.arduino.close() 81 | 82 | def write(self, data): 83 | """ 84 | write the data to the serial port 85 | return: None 86 | """ 87 | self.arduino.write(data) 88 | 89 | def run(self): 90 | """ 91 | This method continually runs. If an incoming character is available on the serial port 92 | it is read and placed on the _command_deque 93 | @return: Never Returns 94 | """ 95 | while 1: 96 | # we can get an OSError: [Errno9] Bad file descriptor when shutting down 97 | # just ignore it 98 | try: 99 | if self.arduino.inWaiting(): 100 | c = self.arduino.read() 101 | self.command_deque.append(ord(c)) 102 | except OSError: 103 | pass 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/log/s2a_fm_debugging.log: -------------------------------------------------------------------------------- 1 | INFO:root:s2a_fm version 1.2 Copyright(C) 2013-14 Alan Yorinks All Rights Reserved 2 | INFO:root:com port = /dev/ttyATH0 3 | INFO:root:30 Total Pins and 12 Analog Pins Found 4 | INFO:root:scratch_http_server.py: keyboard interrupt exception 5 | INFO:root:s2a_fm.py: keyboard interrupt exception 6 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/s2a_fm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # -*- coding: utf-8 -*- 4 | 5 | """ 6 | Created on Wed Nov 25 13:17:15 2013 7 | 8 | @author: Alan Yorinks 9 | Copyright (c) 2013-14 Alan Yorinks All right reserved. 10 | 11 | This program is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU Lesser General Public 13 | License as published by the Free Software Foundation; either 14 | version 2.1 of the License, or (at your option) any later version. 15 | 16 | This library is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public 22 | License along with this library; if not, write to the Free Software 23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 | 25 | """ 26 | import os 27 | import sys 28 | import logging 29 | from PyMata.pymata import PyMata 30 | import scratch_http_server 31 | from scratch_command_handlers import ScratchCommandHandlers 32 | import time 33 | 34 | 35 | #noinspection PyBroadException 36 | def s2a_fm(): 37 | 38 | """ 39 | This is the "main" function of the program. 40 | It will instantiate PyMata for communication with an Arduino micro-controller 41 | and the command handlers class. 42 | It will the start the HTTP server to communicate with Scratch 2.0 43 | @return : This is the main loop and should never return 44 | """ 45 | # total number of pins on arduino board 46 | total_pins_discovered = 0 47 | # number of pins that are analog 48 | number_of_analog_pins_discovered = 0 49 | 50 | # make sure we have a log directory and if not, create it. 51 | if not os.path.exists('log'): 52 | os.makedirs('log') 53 | 54 | # turn on logging 55 | logging.basicConfig(filename='./log/s2a_fm_debugging.log', filemode='w', level=logging.DEBUG) 56 | logging.info('s2a_fm version 1.2 Copyright(C) 2013-14 Alan Yorinks All Rights Reserved ') 57 | print 's2a_fm version 1.2 Copyright(C) 2013-14 Alan Yorinks All Rights Reserved ' 58 | 59 | # get the com_port from the command line or default if none given 60 | # if user specified the com port on the command line, use that when invoking PyMata, 61 | # else use '/dev/ttyACM0' 62 | if len(sys.argv) == 2: 63 | com_port= str(sys.argv[1]) 64 | else: 65 | com_port = '/dev/ttyATH0' 66 | logging.info('com port = %s' % com_port) 67 | 68 | try: 69 | # instantiate PyMata 70 | firmata = PyMata(com_port) # pragma: no cover 71 | except Exception: 72 | print 'Could not instantiate PyMata - is your Arduino plugged in?' 73 | logging.exception('Could not instantiate PyMata - is your Arduino plugged in?') 74 | logging.debug("Exiting s2a_fm") 75 | return 76 | 77 | # determine the total number of pins and the number of analog pins for the Arduino 78 | # get the arduino analog pin map 79 | # it will contain an entry for all the pins with non-analog set to firmata.IGNORE 80 | firmata.analog_mapping_query() 81 | 82 | capability_map = firmata.get_analog_mapping_request_results() 83 | 84 | firmata.capability_query() 85 | print "Please wait for Total Arduino Pin Discovery to complete. This can take up to 30 additional seconds." 86 | 87 | # count the pins 88 | for pin in capability_map: 89 | total_pins_discovered += 1 90 | # non analog pins will be marked as IGNORE 91 | if pin != firmata.IGNORE: 92 | number_of_analog_pins_discovered += 1 93 | 94 | # log the number of pins found 95 | logging.info('%d Total Pins and %d Analog Pins Found' % (total_pins_discovered, 96 | number_of_analog_pins_discovered)) 97 | 98 | # instantiate the command handler 99 | scratch_command_handler = ScratchCommandHandlers(firmata, com_port, total_pins_discovered, 100 | number_of_analog_pins_discovered) 101 | 102 | # wait for a maximum of 30 seconds to retrieve the Arduino capability query 103 | start_time = time.time() 104 | 105 | pin_capability = firmata.get_capability_query_results() 106 | while not pin_capability: 107 | if time.time() - start_time > 30: 108 | print '' 109 | print "Could not determine pin capability - exiting." 110 | firmata.close() 111 | # keep sending out a capability query until there is a response 112 | pin_capability = firmata.get_capability_query_results() 113 | time.sleep(.5) 114 | 115 | # we've got the capability, now build a dictionary with pin as the key and a list of all the capabilities 116 | # for the pin as the key's value 117 | pin_list = [] 118 | total_pins_discovered = 0 119 | for entry in pin_capability: 120 | # bump up pin counter each time IGNORE is found 121 | if entry == firmata.IGNORE: 122 | scratch_command_handler.pin_map[total_pins_discovered] = pin_list 123 | total_pins_discovered += 1 124 | pin_list = [] 125 | else: 126 | pin_list.append(entry) 127 | 128 | print "Arduino Total Pin Discovery completed in %d seconds" % (int(time.time() - start_time)) 129 | 130 | 131 | try: 132 | # start the server passing it the handle to PyMata and the command handler. 133 | scratch_http_server.start_server(firmata, scratch_command_handler) 134 | 135 | except Exception: 136 | logging.debug('Exception in s2a_fm.py %s' % str(Exception)) 137 | firmata.close() 138 | return 139 | 140 | except KeyboardInterrupt: 141 | # give control back to the shell that started us 142 | logging.info('s2a_fm.py: keyboard interrupt exception') 143 | firmata.close() 144 | return 145 | 146 | if __name__ == "__main__": 147 | s2a_fm() 148 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/scratch_http_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon Nov 25 14:45:49 2013 4 | 5 | @author: Alan Yorinks 6 | Copyright (c) 2013-14 Alan Yorinks All right reserved. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | """ 22 | 23 | import logging 24 | from BaseHTTPServer import BaseHTTPRequestHandler 25 | from BaseHTTPServer import HTTPServer 26 | from string import split 27 | 28 | 29 | class GetHandler(BaseHTTPRequestHandler): 30 | """ 31 | This class contains the HTTP server that Scratch2 communicates with 32 | Scratch sends HTTP GET requests and this class processes the requests. 33 | 34 | HTTP GET requests are accepted and the appropriate command handler is 35 | called to process the command. 36 | """ 37 | 38 | firmata = None 39 | 40 | # tcp server port - must match that in the .s2e descriptor file 41 | port = 50209 42 | 43 | # instance handle for the scratch command handler 44 | scratch_command_handler = None 45 | 46 | #indicator so that we can tell user Scratch is ready to go 47 | waiting_for_first_scratch_poll = True 48 | 49 | # this is a 'classmethod' because we need to set data before starting 50 | # the HTTP server. 51 | #noinspection PyMethodParameters 52 | @classmethod 53 | def set_items(self, firmata, scratch_command_handler): 54 | """ 55 | This method stores the input parameters for later use. 56 | It is a class method, because these values need to established 57 | prior to instantiating the class 58 | """ 59 | # instance variable for PyMata 60 | #noinspection PyAttributeOutsideInit 61 | self.firmata = firmata 62 | 63 | # instance variable for scratch command handler 64 | #noinspection PyAttributeOutsideInit 65 | self.command_handler = scratch_command_handler 66 | 67 | #noinspection PyPep8Naming 68 | def do_GET(self): 69 | """ 70 | Scratch2 only sends HTTP GET commands. This method processes them. 71 | It differentiates between a "normal" command request and a request 72 | to send policy information to keep Flash happy on Scratch. 73 | (This may change when Scratch is converted to HTML 5 74 | """ 75 | 76 | # skip over the / in the command 77 | cmd = self.path[1:] 78 | # create a list containing the command and all of its parameters 79 | cmd_list = split(cmd, '/') 80 | 81 | # get the command handler method for the command and call the handler 82 | # cmd_list[0] contains the command. look up the command method 83 | s = self.command_handler.do_command(cmd_list) 84 | 85 | self.send_resp(s) 86 | 87 | 88 | # we can't use the standard send_response since we don't conform to its 89 | # standards, so we craft our own response handler here 90 | def send_resp(self, response): 91 | """ 92 | This method sends Scratch an HTTP response to an HTTP GET command. 93 | """ 94 | 95 | crlf = "\r\n" 96 | # http_response = str(response + crlf) 97 | http_response = "HTTP/1.1 200 OK" + crlf 98 | http_response += "Content-Type: text/html; charset=ISO-8859-1" + crlf 99 | http_response += "Content-Length" + str(len(response)) + crlf 100 | http_response += "Access-Control-Allow-Origin: *" + crlf 101 | http_response += crlf 102 | #add the response to the nonsense above 103 | if response != 'okay': 104 | http_response += str(response + crlf) 105 | # send it out the door to Scratch 106 | self.wfile.write(http_response) 107 | 108 | def start_server(firmata, command_handler): 109 | """ 110 | This function populates class variables with essential data and 111 | instantiates the HTTP Server 112 | """ 113 | 114 | GetHandler.set_items(firmata, command_handler) 115 | try: 116 | server = HTTPServer(('192.168.2.189', 50209), GetHandler) 117 | print 'Starting HTTP Server!' 118 | print 'Use to exit the extension\n' 119 | print 'Please start Scratch or Snap!' 120 | except Exception: 121 | logging.debug('Exception in scratch_http_server.py: HTTP Socket may already be in use - restart Scratch') 122 | print 'HTTP Socket may already be in use - restart Scratch' 123 | raise 124 | try: 125 | #start the server 126 | server.serve_forever() 127 | except KeyboardInterrupt: 128 | logging.info('scratch_http_server.py: keyboard interrupt exception') 129 | print "Goodbye !" 130 | raise KeyboardInterrupt 131 | except Exception: 132 | logging.debug('scratch_http_server.py: Exception %s' % str(Exception)) 133 | raise -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # portable serial port access with python 4 | # this is a wrapper module for different platform implementations 5 | # 6 | # (C) 2001-2010 Chris Liechti 7 | # this is distributed under a free software license, see license.txt 8 | 9 | VERSION = '2.7' 10 | 11 | import sys 12 | 13 | if sys.platform == 'cli': 14 | from serial.serialcli import * 15 | else: 16 | import os 17 | # chose an implementation, depending on os 18 | if os.name == 'nt': #sys.platform == 'win32': 19 | from serial.serialwin32 import * 20 | elif os.name == 'posix': 21 | from serial.serialposix import * 22 | elif os.name == 'java': 23 | from serial.serialjava import * 24 | else: 25 | raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,)) 26 | 27 | 28 | protocol_handler_packages = [ 29 | 'serial.urlhandler', 30 | ] 31 | 32 | def serial_for_url(url, *args, **kwargs): 33 | """\ 34 | Get an instance of the Serial class, depending on port/url. The port is not 35 | opened when the keyword parameter 'do_not_open' is true, by default it 36 | is. All other parameters are directly passed to the __init__ method when 37 | the port is instantiated. 38 | 39 | The list of package names that is searched for protocol handlers is kept in 40 | ``protocol_handler_packages``. 41 | 42 | e.g. we want to support a URL ``foobar://``. A module 43 | ``my_handlers.protocol_foobar`` is provided by the user. Then 44 | ``protocol_handler_packages.append("my_handlers")`` would extend the search 45 | path so that ``serial_for_url("foobar://"))`` would work. 46 | """ 47 | # check remove extra parameter to not confuse the Serial class 48 | do_open = 'do_not_open' not in kwargs or not kwargs['do_not_open'] 49 | if 'do_not_open' in kwargs: del kwargs['do_not_open'] 50 | # the default is to use the native version 51 | klass = Serial # 'native' implementation 52 | # check port type and get class 53 | try: 54 | url_nocase = url.lower() 55 | except AttributeError: 56 | # it's not a string, use default 57 | pass 58 | else: 59 | if '://' in url_nocase: 60 | protocol = url_nocase.split('://', 1)[0] 61 | for package_name in protocol_handler_packages: 62 | module_name = '%s.protocol_%s' % (package_name, protocol,) 63 | try: 64 | handler_module = __import__(module_name) 65 | except ImportError: 66 | pass 67 | else: 68 | klass = sys.modules[module_name].Serial 69 | break 70 | else: 71 | raise ValueError('invalid URL, protocol %r not known' % (protocol,)) 72 | else: 73 | klass = Serial # 'native' implementation 74 | # instantiate and open when desired 75 | instance = klass(None, *args, **kwargs) 76 | instance.port = url 77 | if do_open: 78 | instance.open() 79 | return instance 80 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/serialcli.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # Python Serial Port Extension for Win32, Linux, BSD, Jython and .NET/Mono 3 | # serial driver for .NET/Mono (IronPython), .NET >= 2 4 | # see __init__.py 5 | # 6 | # (C) 2008 Chris Liechti 7 | # this is distributed under a free software license, see license.txt 8 | 9 | import clr 10 | import System 11 | import System.IO.Ports 12 | from serial.serialutil import * 13 | 14 | 15 | def device(portnum): 16 | """Turn a port number into a device name""" 17 | return System.IO.Ports.SerialPort.GetPortNames()[portnum] 18 | 19 | 20 | # must invoke function with byte array, make a helper to convert strings 21 | # to byte arrays 22 | sab = System.Array[System.Byte] 23 | def as_byte_array(string): 24 | return sab([ord(x) for x in string]) # XXX will require adaption when run with a 3.x compatible IronPython 25 | 26 | class IronSerial(SerialBase): 27 | """Serial port implementation for .NET/Mono.""" 28 | 29 | BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 30 | 9600, 19200, 38400, 57600, 115200) 31 | 32 | def open(self): 33 | """Open port with current settings. This may throw a SerialException 34 | if the port cannot be opened.""" 35 | if self._port is None: 36 | raise SerialException("Port must be configured before it can be used.") 37 | if self._isOpen: 38 | raise SerialException("Port is already open.") 39 | try: 40 | self._port_handle = System.IO.Ports.SerialPort(self.portstr) 41 | except Exception, msg: 42 | self._port_handle = None 43 | raise SerialException("could not open port %s: %s" % (self.portstr, msg)) 44 | 45 | self._reconfigurePort() 46 | self._port_handle.Open() 47 | self._isOpen = True 48 | if not self._rtscts: 49 | self.setRTS(True) 50 | self.setDTR(True) 51 | self.flushInput() 52 | self.flushOutput() 53 | 54 | def _reconfigurePort(self): 55 | """Set communication parameters on opened port.""" 56 | if not self._port_handle: 57 | raise SerialException("Can only operate on a valid port handle") 58 | 59 | #~ self._port_handle.ReceivedBytesThreshold = 1 60 | 61 | if self._timeout is None: 62 | self._port_handle.ReadTimeout = System.IO.Ports.SerialPort.InfiniteTimeout 63 | else: 64 | self._port_handle.ReadTimeout = int(self._timeout*1000) 65 | 66 | # if self._timeout != 0 and self._interCharTimeout is not None: 67 | # timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:] 68 | 69 | if self._writeTimeout is None: 70 | self._port_handle.WriteTimeout = System.IO.Ports.SerialPort.InfiniteTimeout 71 | else: 72 | self._port_handle.WriteTimeout = int(self._writeTimeout*1000) 73 | 74 | 75 | # Setup the connection info. 76 | try: 77 | self._port_handle.BaudRate = self._baudrate 78 | except IOError, e: 79 | # catch errors from illegal baudrate settings 80 | raise ValueError(str(e)) 81 | 82 | if self._bytesize == FIVEBITS: 83 | self._port_handle.DataBits = 5 84 | elif self._bytesize == SIXBITS: 85 | self._port_handle.DataBits = 6 86 | elif self._bytesize == SEVENBITS: 87 | self._port_handle.DataBits = 7 88 | elif self._bytesize == EIGHTBITS: 89 | self._port_handle.DataBits = 8 90 | else: 91 | raise ValueError("Unsupported number of data bits: %r" % self._bytesize) 92 | 93 | if self._parity == PARITY_NONE: 94 | self._port_handle.Parity = getattr(System.IO.Ports.Parity, 'None') # reserved keyword in Py3k 95 | elif self._parity == PARITY_EVEN: 96 | self._port_handle.Parity = System.IO.Ports.Parity.Even 97 | elif self._parity == PARITY_ODD: 98 | self._port_handle.Parity = System.IO.Ports.Parity.Odd 99 | elif self._parity == PARITY_MARK: 100 | self._port_handle.Parity = System.IO.Ports.Parity.Mark 101 | elif self._parity == PARITY_SPACE: 102 | self._port_handle.Parity = System.IO.Ports.Parity.Space 103 | else: 104 | raise ValueError("Unsupported parity mode: %r" % self._parity) 105 | 106 | if self._stopbits == STOPBITS_ONE: 107 | self._port_handle.StopBits = System.IO.Ports.StopBits.One 108 | elif self._stopbits == STOPBITS_ONE_POINT_FIVE: 109 | self._port_handle.StopBits = System.IO.Ports.StopBits.OnePointFive 110 | elif self._stopbits == STOPBITS_TWO: 111 | self._port_handle.StopBits = System.IO.Ports.StopBits.Two 112 | else: 113 | raise ValueError("Unsupported number of stop bits: %r" % self._stopbits) 114 | 115 | if self._rtscts and self._xonxoff: 116 | self._port_handle.Handshake = System.IO.Ports.Handshake.RequestToSendXOnXOff 117 | elif self._rtscts: 118 | self._port_handle.Handshake = System.IO.Ports.Handshake.RequestToSend 119 | elif self._xonxoff: 120 | self._port_handle.Handshake = System.IO.Ports.Handshake.XOnXOff 121 | else: 122 | self._port_handle.Handshake = getattr(System.IO.Ports.Handshake, 'None') # reserved keyword in Py3k 123 | 124 | #~ def __del__(self): 125 | #~ self.close() 126 | 127 | def close(self): 128 | """Close port""" 129 | if self._isOpen: 130 | if self._port_handle: 131 | try: 132 | self._port_handle.Close() 133 | except System.IO.Ports.InvalidOperationException: 134 | # ignore errors. can happen for unplugged USB serial devices 135 | pass 136 | self._port_handle = None 137 | self._isOpen = False 138 | 139 | def makeDeviceName(self, port): 140 | try: 141 | return device(port) 142 | except TypeError, e: 143 | raise SerialException(str(e)) 144 | 145 | # - - - - - - - - - - - - - - - - - - - - - - - - 146 | 147 | def inWaiting(self): 148 | """Return the number of characters currently in the input buffer.""" 149 | if not self._port_handle: raise portNotOpenError 150 | return self._port_handle.BytesToRead 151 | 152 | def read(self, size=1): 153 | """Read size bytes from the serial port. If a timeout is set it may 154 | return less characters as requested. With no timeout it will block 155 | until the requested number of bytes is read.""" 156 | if not self._port_handle: raise portNotOpenError 157 | # must use single byte reads as this is the only way to read 158 | # without applying encodings 159 | data = bytearray() 160 | while size: 161 | try: 162 | data.append(self._port_handle.ReadByte()) 163 | except System.TimeoutException, e: 164 | break 165 | else: 166 | size -= 1 167 | return bytes(data) 168 | 169 | def write(self, data): 170 | """Output the given string over the serial port.""" 171 | if not self._port_handle: raise portNotOpenError 172 | if not isinstance(data, (bytes, bytearray)): 173 | raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data))) 174 | try: 175 | # must call overloaded method with byte array argument 176 | # as this is the only one not applying encodings 177 | self._port_handle.Write(as_byte_array(data), 0, len(data)) 178 | except System.TimeoutException, e: 179 | raise writeTimeoutError 180 | return len(data) 181 | 182 | def flushInput(self): 183 | """Clear input buffer, discarding all that is in the buffer.""" 184 | if not self._port_handle: raise portNotOpenError 185 | self._port_handle.DiscardInBuffer() 186 | 187 | def flushOutput(self): 188 | """Clear output buffer, aborting the current output and 189 | discarding all that is in the buffer.""" 190 | if not self._port_handle: raise portNotOpenError 191 | self._port_handle.DiscardOutBuffer() 192 | 193 | def sendBreak(self, duration=0.25): 194 | """Send break condition. Timed, returns to idle state after given duration.""" 195 | if not self._port_handle: raise portNotOpenError 196 | import time 197 | self._port_handle.BreakState = True 198 | time.sleep(duration) 199 | self._port_handle.BreakState = False 200 | 201 | def setBreak(self, level=True): 202 | """Set break: Controls TXD. When active, to transmitting is possible.""" 203 | if not self._port_handle: raise portNotOpenError 204 | self._port_handle.BreakState = bool(level) 205 | 206 | def setRTS(self, level=True): 207 | """Set terminal status line: Request To Send""" 208 | if not self._port_handle: raise portNotOpenError 209 | self._port_handle.RtsEnable = bool(level) 210 | 211 | def setDTR(self, level=True): 212 | """Set terminal status line: Data Terminal Ready""" 213 | if not self._port_handle: raise portNotOpenError 214 | self._port_handle.DtrEnable = bool(level) 215 | 216 | def getCTS(self): 217 | """Read terminal status line: Clear To Send""" 218 | if not self._port_handle: raise portNotOpenError 219 | return self._port_handle.CtsHolding 220 | 221 | def getDSR(self): 222 | """Read terminal status line: Data Set Ready""" 223 | if not self._port_handle: raise portNotOpenError 224 | return self._port_handle.DsrHolding 225 | 226 | def getRI(self): 227 | """Read terminal status line: Ring Indicator""" 228 | if not self._port_handle: raise portNotOpenError 229 | #~ return self._port_handle.XXX 230 | return False #XXX an error would be better 231 | 232 | def getCD(self): 233 | """Read terminal status line: Carrier Detect""" 234 | if not self._port_handle: raise portNotOpenError 235 | return self._port_handle.CDHolding 236 | 237 | # - - platform specific - - - - 238 | # none 239 | 240 | 241 | # assemble Serial class with the platform specific implementation and the base 242 | # for file-like behavior. for Python 2.6 and newer, that provide the new I/O 243 | # library, derive from io.RawIOBase 244 | try: 245 | import io 246 | except ImportError: 247 | # classic version with our own file-like emulation 248 | class Serial(IronSerial, FileLike): 249 | pass 250 | else: 251 | # io library present 252 | class Serial(IronSerial, io.RawIOBase): 253 | pass 254 | 255 | 256 | # Nur Testfunktion!! 257 | if __name__ == '__main__': 258 | import sys 259 | 260 | s = Serial(0) 261 | sys.stdio.write('%s\n' % s) 262 | 263 | s = Serial() 264 | sys.stdio.write('%s\n' % s) 265 | 266 | 267 | s.baudrate = 19200 268 | s.databits = 7 269 | s.close() 270 | s.port = 0 271 | s.open() 272 | sys.stdio.write('%s\n' % s) 273 | 274 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/serialjava.py: -------------------------------------------------------------------------------- 1 | #!jython 2 | # 3 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 4 | # module for serial IO for Jython and JavaComm 5 | # see __init__.py 6 | # 7 | # (C) 2002-2008 Chris Liechti 8 | # this is distributed under a free software license, see license.txt 9 | 10 | from serial.serialutil import * 11 | 12 | def my_import(name): 13 | mod = __import__(name) 14 | components = name.split('.') 15 | for comp in components[1:]: 16 | mod = getattr(mod, comp) 17 | return mod 18 | 19 | 20 | def detect_java_comm(names): 21 | """try given list of modules and return that imports""" 22 | for name in names: 23 | try: 24 | mod = my_import(name) 25 | mod.SerialPort 26 | return mod 27 | except (ImportError, AttributeError): 28 | pass 29 | raise ImportError("No Java Communications API implementation found") 30 | 31 | 32 | # Java Communications API implementations 33 | # http://mho.republika.pl/java/comm/ 34 | 35 | comm = detect_java_comm([ 36 | 'javax.comm', # Sun/IBM 37 | 'gnu.io', # RXTX 38 | ]) 39 | 40 | 41 | def device(portnumber): 42 | """Turn a port number into a device name""" 43 | enum = comm.CommPortIdentifier.getPortIdentifiers() 44 | ports = [] 45 | while enum.hasMoreElements(): 46 | el = enum.nextElement() 47 | if el.getPortType() == comm.CommPortIdentifier.PORT_SERIAL: 48 | ports.append(el) 49 | return ports[portnumber].getName() 50 | 51 | 52 | class JavaSerial(SerialBase): 53 | """Serial port class, implemented with Java Communications API and 54 | thus usable with jython and the appropriate java extension.""" 55 | 56 | def open(self): 57 | """Open port with current settings. This may throw a SerialException 58 | if the port cannot be opened.""" 59 | if self._port is None: 60 | raise SerialException("Port must be configured before it can be used.") 61 | if self._isOpen: 62 | raise SerialException("Port is already open.") 63 | if type(self._port) == type(''): # strings are taken directly 64 | portId = comm.CommPortIdentifier.getPortIdentifier(self._port) 65 | else: 66 | portId = comm.CommPortIdentifier.getPortIdentifier(device(self._port)) # numbers are transformed to a comport id obj 67 | try: 68 | self.sPort = portId.open("python serial module", 10) 69 | except Exception, msg: 70 | self.sPort = None 71 | raise SerialException("Could not open port: %s" % msg) 72 | self._reconfigurePort() 73 | self._instream = self.sPort.getInputStream() 74 | self._outstream = self.sPort.getOutputStream() 75 | self._isOpen = True 76 | 77 | def _reconfigurePort(self): 78 | """Set communication parameters on opened port.""" 79 | if not self.sPort: 80 | raise SerialException("Can only operate on a valid port handle") 81 | 82 | self.sPort.enableReceiveTimeout(30) 83 | if self._bytesize == FIVEBITS: 84 | jdatabits = comm.SerialPort.DATABITS_5 85 | elif self._bytesize == SIXBITS: 86 | jdatabits = comm.SerialPort.DATABITS_6 87 | elif self._bytesize == SEVENBITS: 88 | jdatabits = comm.SerialPort.DATABITS_7 89 | elif self._bytesize == EIGHTBITS: 90 | jdatabits = comm.SerialPort.DATABITS_8 91 | else: 92 | raise ValueError("unsupported bytesize: %r" % self._bytesize) 93 | 94 | if self._stopbits == STOPBITS_ONE: 95 | jstopbits = comm.SerialPort.STOPBITS_1 96 | elif stopbits == STOPBITS_ONE_POINT_FIVE: 97 | self._jstopbits = comm.SerialPort.STOPBITS_1_5 98 | elif self._stopbits == STOPBITS_TWO: 99 | jstopbits = comm.SerialPort.STOPBITS_2 100 | else: 101 | raise ValueError("unsupported number of stopbits: %r" % self._stopbits) 102 | 103 | if self._parity == PARITY_NONE: 104 | jparity = comm.SerialPort.PARITY_NONE 105 | elif self._parity == PARITY_EVEN: 106 | jparity = comm.SerialPort.PARITY_EVEN 107 | elif self._parity == PARITY_ODD: 108 | jparity = comm.SerialPort.PARITY_ODD 109 | elif self._parity == PARITY_MARK: 110 | jparity = comm.SerialPort.PARITY_MARK 111 | elif self._parity == PARITY_SPACE: 112 | jparity = comm.SerialPort.PARITY_SPACE 113 | else: 114 | raise ValueError("unsupported parity type: %r" % self._parity) 115 | 116 | jflowin = jflowout = 0 117 | if self._rtscts: 118 | jflowin |= comm.SerialPort.FLOWCONTROL_RTSCTS_IN 119 | jflowout |= comm.SerialPort.FLOWCONTROL_RTSCTS_OUT 120 | if self._xonxoff: 121 | jflowin |= comm.SerialPort.FLOWCONTROL_XONXOFF_IN 122 | jflowout |= comm.SerialPort.FLOWCONTROL_XONXOFF_OUT 123 | 124 | self.sPort.setSerialPortParams(self._baudrate, jdatabits, jstopbits, jparity) 125 | self.sPort.setFlowControlMode(jflowin | jflowout) 126 | 127 | if self._timeout >= 0: 128 | self.sPort.enableReceiveTimeout(self._timeout*1000) 129 | else: 130 | self.sPort.disableReceiveTimeout() 131 | 132 | def close(self): 133 | """Close port""" 134 | if self._isOpen: 135 | if self.sPort: 136 | self._instream.close() 137 | self._outstream.close() 138 | self.sPort.close() 139 | self.sPort = None 140 | self._isOpen = False 141 | 142 | def makeDeviceName(self, port): 143 | return device(port) 144 | 145 | # - - - - - - - - - - - - - - - - - - - - - - - - 146 | 147 | def inWaiting(self): 148 | """Return the number of characters currently in the input buffer.""" 149 | if not self.sPort: raise portNotOpenError 150 | return self._instream.available() 151 | 152 | def read(self, size=1): 153 | """Read size bytes from the serial port. If a timeout is set it may 154 | return less characters as requested. With no timeout it will block 155 | until the requested number of bytes is read.""" 156 | if not self.sPort: raise portNotOpenError 157 | read = bytearray() 158 | if size > 0: 159 | while len(read) < size: 160 | x = self._instream.read() 161 | if x == -1: 162 | if self.timeout >= 0: 163 | break 164 | else: 165 | read.append(x) 166 | return bytes(read) 167 | 168 | def write(self, data): 169 | """Output the given string over the serial port.""" 170 | if not self.sPort: raise portNotOpenError 171 | if not isinstance(data, (bytes, bytearray)): 172 | raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data))) 173 | self._outstream.write(data) 174 | return len(data) 175 | 176 | def flushInput(self): 177 | """Clear input buffer, discarding all that is in the buffer.""" 178 | if not self.sPort: raise portNotOpenError 179 | self._instream.skip(self._instream.available()) 180 | 181 | def flushOutput(self): 182 | """Clear output buffer, aborting the current output and 183 | discarding all that is in the buffer.""" 184 | if not self.sPort: raise portNotOpenError 185 | self._outstream.flush() 186 | 187 | def sendBreak(self, duration=0.25): 188 | """Send break condition. Timed, returns to idle state after given duration.""" 189 | if not self.sPort: raise portNotOpenError 190 | self.sPort.sendBreak(duration*1000.0) 191 | 192 | def setBreak(self, level=1): 193 | """Set break: Controls TXD. When active, to transmitting is possible.""" 194 | if self.fd is None: raise portNotOpenError 195 | raise SerialException("The setBreak function is not implemented in java.") 196 | 197 | def setRTS(self, level=1): 198 | """Set terminal status line: Request To Send""" 199 | if not self.sPort: raise portNotOpenError 200 | self.sPort.setRTS(level) 201 | 202 | def setDTR(self, level=1): 203 | """Set terminal status line: Data Terminal Ready""" 204 | if not self.sPort: raise portNotOpenError 205 | self.sPort.setDTR(level) 206 | 207 | def getCTS(self): 208 | """Read terminal status line: Clear To Send""" 209 | if not self.sPort: raise portNotOpenError 210 | self.sPort.isCTS() 211 | 212 | def getDSR(self): 213 | """Read terminal status line: Data Set Ready""" 214 | if not self.sPort: raise portNotOpenError 215 | self.sPort.isDSR() 216 | 217 | def getRI(self): 218 | """Read terminal status line: Ring Indicator""" 219 | if not self.sPort: raise portNotOpenError 220 | self.sPort.isRI() 221 | 222 | def getCD(self): 223 | """Read terminal status line: Carrier Detect""" 224 | if not self.sPort: raise portNotOpenError 225 | self.sPort.isCD() 226 | 227 | 228 | # assemble Serial class with the platform specific implementation and the base 229 | # for file-like behavior. for Python 2.6 and newer, that provide the new I/O 230 | # library, derive from io.RawIOBase 231 | try: 232 | import io 233 | except ImportError: 234 | # classic version with our own file-like emulation 235 | class Serial(JavaSerial, FileLike): 236 | pass 237 | else: 238 | # io library present 239 | class Serial(JavaSerial, io.RawIOBase): 240 | pass 241 | 242 | 243 | if __name__ == '__main__': 244 | s = Serial(0, 245 | baudrate=19200, # baudrate 246 | bytesize=EIGHTBITS, # number of databits 247 | parity=PARITY_EVEN, # enable parity checking 248 | stopbits=STOPBITS_ONE, # number of stopbits 249 | timeout=3, # set a timeout value, None for waiting forever 250 | xonxoff=0, # enable software flow control 251 | rtscts=0, # enable RTS/CTS flow control 252 | ) 253 | s.setRTS(1) 254 | s.setDTR(1) 255 | s.flushInput() 256 | s.flushOutput() 257 | s.write('hello') 258 | sys.stdio.write('%r\n' % s.read(5)) 259 | sys.stdio.write('%s\n' % s.inWaiting()) 260 | del s 261 | 262 | 263 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/serialwin32.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 3 | # serial driver for win32 4 | # see __init__.py 5 | # 6 | # (C) 2001-2011 Chris Liechti 7 | # this is distributed under a free software license, see license.txt 8 | # 9 | # Initial patch to use ctypes by Giovanni Bajo 10 | 11 | import ctypes 12 | from serial import win32 13 | 14 | from serial.serialutil import * 15 | 16 | 17 | def device(portnum): 18 | """Turn a port number into a device name""" 19 | return 'COM%d' % (portnum+1) # numbers are transformed to a string 20 | 21 | 22 | class Win32Serial(SerialBase): 23 | """Serial port implementation for Win32 based on ctypes.""" 24 | 25 | BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 26 | 9600, 19200, 38400, 57600, 115200) 27 | 28 | def __init__(self, *args, **kwargs): 29 | self.hComPort = None 30 | self._overlappedRead = None 31 | self._overlappedWrite = None 32 | self._rtsToggle = False 33 | 34 | self._rtsState = win32.RTS_CONTROL_ENABLE 35 | self._dtrState = win32.DTR_CONTROL_ENABLE 36 | 37 | 38 | SerialBase.__init__(self, *args, **kwargs) 39 | 40 | def open(self): 41 | """Open port with current settings. This may throw a SerialException 42 | if the port cannot be opened.""" 43 | if self._port is None: 44 | raise SerialException("Port must be configured before it can be used.") 45 | if self._isOpen: 46 | raise SerialException("Port is already open.") 47 | # the "\\.\COMx" format is required for devices other than COM1-COM8 48 | # not all versions of windows seem to support this properly 49 | # so that the first few ports are used with the DOS device name 50 | port = self.portstr 51 | try: 52 | if port.upper().startswith('COM') and int(port[3:]) > 8: 53 | port = '\\\\.\\' + port 54 | except ValueError: 55 | # for like COMnotanumber 56 | pass 57 | self.hComPort = win32.CreateFile(port, 58 | win32.GENERIC_READ | win32.GENERIC_WRITE, 59 | 0, # exclusive access 60 | None, # no security 61 | win32.OPEN_EXISTING, 62 | win32.FILE_ATTRIBUTE_NORMAL | win32.FILE_FLAG_OVERLAPPED, 63 | 0) 64 | if self.hComPort == win32.INVALID_HANDLE_VALUE: 65 | self.hComPort = None # 'cause __del__ is called anyway 66 | raise SerialException("could not open port %r: %r" % (self.portstr, ctypes.WinError())) 67 | 68 | try: 69 | self._overlappedRead = win32.OVERLAPPED() 70 | self._overlappedRead.hEvent = win32.CreateEvent(None, 1, 0, None) 71 | self._overlappedWrite = win32.OVERLAPPED() 72 | #~ self._overlappedWrite.hEvent = win32.CreateEvent(None, 1, 0, None) 73 | self._overlappedWrite.hEvent = win32.CreateEvent(None, 0, 0, None) 74 | 75 | # Setup a 4k buffer 76 | win32.SetupComm(self.hComPort, 4096, 4096) 77 | 78 | # Save original timeout values: 79 | self._orgTimeouts = win32.COMMTIMEOUTS() 80 | win32.GetCommTimeouts(self.hComPort, ctypes.byref(self._orgTimeouts)) 81 | 82 | self._reconfigurePort() 83 | 84 | # Clear buffers: 85 | # Remove anything that was there 86 | win32.PurgeComm(self.hComPort, 87 | win32.PURGE_TXCLEAR | win32.PURGE_TXABORT | 88 | win32.PURGE_RXCLEAR | win32.PURGE_RXABORT) 89 | except: 90 | try: 91 | self._close() 92 | except: 93 | # ignore any exception when closing the port 94 | # also to keep original exception that happened when setting up 95 | pass 96 | self.hComPort = None 97 | raise 98 | else: 99 | self._isOpen = True 100 | 101 | 102 | def _reconfigurePort(self): 103 | """Set communication parameters on opened port.""" 104 | if not self.hComPort: 105 | raise SerialException("Can only operate on a valid port handle") 106 | 107 | # Set Windows timeout values 108 | # timeouts is a tuple with the following items: 109 | # (ReadIntervalTimeout,ReadTotalTimeoutMultiplier, 110 | # ReadTotalTimeoutConstant,WriteTotalTimeoutMultiplier, 111 | # WriteTotalTimeoutConstant) 112 | if self._timeout is None: 113 | timeouts = (0, 0, 0, 0, 0) 114 | elif self._timeout == 0: 115 | timeouts = (win32.MAXDWORD, 0, 0, 0, 0) 116 | else: 117 | timeouts = (0, 0, int(self._timeout*1000), 0, 0) 118 | if self._timeout != 0 and self._interCharTimeout is not None: 119 | timeouts = (int(self._interCharTimeout * 1000),) + timeouts[1:] 120 | 121 | if self._writeTimeout is None: 122 | pass 123 | elif self._writeTimeout == 0: 124 | timeouts = timeouts[:-2] + (0, win32.MAXDWORD) 125 | else: 126 | timeouts = timeouts[:-2] + (0, int(self._writeTimeout*1000)) 127 | win32.SetCommTimeouts(self.hComPort, ctypes.byref(win32.COMMTIMEOUTS(*timeouts))) 128 | 129 | win32.SetCommMask(self.hComPort, win32.EV_ERR) 130 | 131 | # Setup the connection info. 132 | # Get state and modify it: 133 | comDCB = win32.DCB() 134 | win32.GetCommState(self.hComPort, ctypes.byref(comDCB)) 135 | comDCB.BaudRate = self._baudrate 136 | 137 | if self._bytesize == FIVEBITS: 138 | comDCB.ByteSize = 5 139 | elif self._bytesize == SIXBITS: 140 | comDCB.ByteSize = 6 141 | elif self._bytesize == SEVENBITS: 142 | comDCB.ByteSize = 7 143 | elif self._bytesize == EIGHTBITS: 144 | comDCB.ByteSize = 8 145 | else: 146 | raise ValueError("Unsupported number of data bits: %r" % self._bytesize) 147 | 148 | if self._parity == PARITY_NONE: 149 | comDCB.Parity = win32.NOPARITY 150 | comDCB.fParity = 0 # Disable Parity Check 151 | elif self._parity == PARITY_EVEN: 152 | comDCB.Parity = win32.EVENPARITY 153 | comDCB.fParity = 1 # Enable Parity Check 154 | elif self._parity == PARITY_ODD: 155 | comDCB.Parity = win32.ODDPARITY 156 | comDCB.fParity = 1 # Enable Parity Check 157 | elif self._parity == PARITY_MARK: 158 | comDCB.Parity = win32.MARKPARITY 159 | comDCB.fParity = 1 # Enable Parity Check 160 | elif self._parity == PARITY_SPACE: 161 | comDCB.Parity = win32.SPACEPARITY 162 | comDCB.fParity = 1 # Enable Parity Check 163 | else: 164 | raise ValueError("Unsupported parity mode: %r" % self._parity) 165 | 166 | if self._stopbits == STOPBITS_ONE: 167 | comDCB.StopBits = win32.ONESTOPBIT 168 | elif self._stopbits == STOPBITS_ONE_POINT_FIVE: 169 | comDCB.StopBits = win32.ONE5STOPBITS 170 | elif self._stopbits == STOPBITS_TWO: 171 | comDCB.StopBits = win32.TWOSTOPBITS 172 | else: 173 | raise ValueError("Unsupported number of stop bits: %r" % self._stopbits) 174 | 175 | comDCB.fBinary = 1 # Enable Binary Transmission 176 | # Char. w/ Parity-Err are replaced with 0xff (if fErrorChar is set to TRUE) 177 | if self._rtscts: 178 | comDCB.fRtsControl = win32.RTS_CONTROL_HANDSHAKE 179 | elif self._rtsToggle: 180 | comDCB.fRtsControl = win32.RTS_CONTROL_TOGGLE 181 | else: 182 | comDCB.fRtsControl = self._rtsState 183 | if self._dsrdtr: 184 | comDCB.fDtrControl = win32.DTR_CONTROL_HANDSHAKE 185 | else: 186 | comDCB.fDtrControl = self._dtrState 187 | 188 | if self._rtsToggle: 189 | comDCB.fOutxCtsFlow = 0 190 | else: 191 | comDCB.fOutxCtsFlow = self._rtscts 192 | comDCB.fOutxDsrFlow = self._dsrdtr 193 | comDCB.fOutX = self._xonxoff 194 | comDCB.fInX = self._xonxoff 195 | comDCB.fNull = 0 196 | comDCB.fErrorChar = 0 197 | comDCB.fAbortOnError = 0 198 | comDCB.XonChar = XON 199 | comDCB.XoffChar = XOFF 200 | 201 | if not win32.SetCommState(self.hComPort, ctypes.byref(comDCB)): 202 | raise ValueError("Cannot configure port, some setting was wrong. Original message: %r" % ctypes.WinError()) 203 | 204 | #~ def __del__(self): 205 | #~ self.close() 206 | 207 | 208 | def _close(self): 209 | """internal close port helper""" 210 | if self.hComPort: 211 | # Restore original timeout values: 212 | win32.SetCommTimeouts(self.hComPort, self._orgTimeouts) 213 | # Close COM-Port: 214 | win32.CloseHandle(self.hComPort) 215 | if self._overlappedRead is not None: 216 | win32.CloseHandle(self._overlappedRead.hEvent) 217 | self._overlappedRead = None 218 | if self._overlappedWrite is not None: 219 | win32.CloseHandle(self._overlappedWrite.hEvent) 220 | self._overlappedWrite = None 221 | self.hComPort = None 222 | 223 | def close(self): 224 | """Close port""" 225 | if self._isOpen: 226 | self._close() 227 | self._isOpen = False 228 | 229 | def makeDeviceName(self, port): 230 | return device(port) 231 | 232 | # - - - - - - - - - - - - - - - - - - - - - - - - 233 | 234 | def inWaiting(self): 235 | """Return the number of characters currently in the input buffer.""" 236 | flags = win32.DWORD() 237 | comstat = win32.COMSTAT() 238 | if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)): 239 | raise SerialException('call to ClearCommError failed') 240 | return comstat.cbInQue 241 | 242 | def read(self, size=1): 243 | """Read size bytes from the serial port. If a timeout is set it may 244 | return less characters as requested. With no timeout it will block 245 | until the requested number of bytes is read.""" 246 | if not self.hComPort: raise portNotOpenError 247 | if size > 0: 248 | win32.ResetEvent(self._overlappedRead.hEvent) 249 | flags = win32.DWORD() 250 | comstat = win32.COMSTAT() 251 | if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)): 252 | raise SerialException('call to ClearCommError failed') 253 | if self.timeout == 0: 254 | n = min(comstat.cbInQue, size) 255 | if n > 0: 256 | buf = ctypes.create_string_buffer(n) 257 | rc = win32.DWORD() 258 | err = win32.ReadFile(self.hComPort, buf, n, ctypes.byref(rc), ctypes.byref(self._overlappedRead)) 259 | if not err and win32.GetLastError() != win32.ERROR_IO_PENDING: 260 | raise SerialException("ReadFile failed (%r)" % ctypes.WinError()) 261 | err = win32.WaitForSingleObject(self._overlappedRead.hEvent, win32.INFINITE) 262 | read = buf.raw[:rc.value] 263 | else: 264 | read = bytes() 265 | else: 266 | buf = ctypes.create_string_buffer(size) 267 | rc = win32.DWORD() 268 | err = win32.ReadFile(self.hComPort, buf, size, ctypes.byref(rc), ctypes.byref(self._overlappedRead)) 269 | if not err and win32.GetLastError() != win32.ERROR_IO_PENDING: 270 | raise SerialException("ReadFile failed (%r)" % ctypes.WinError()) 271 | err = win32.GetOverlappedResult(self.hComPort, ctypes.byref(self._overlappedRead), ctypes.byref(rc), True) 272 | read = buf.raw[:rc.value] 273 | else: 274 | read = bytes() 275 | return bytes(read) 276 | 277 | def write(self, data): 278 | """Output the given string over the serial port.""" 279 | if not self.hComPort: raise portNotOpenError 280 | #~ if not isinstance(data, (bytes, bytearray)): 281 | #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data))) 282 | # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview 283 | data = to_bytes(data) 284 | if data: 285 | #~ win32event.ResetEvent(self._overlappedWrite.hEvent) 286 | n = win32.DWORD() 287 | err = win32.WriteFile(self.hComPort, data, len(data), ctypes.byref(n), self._overlappedWrite) 288 | if not err and win32.GetLastError() != win32.ERROR_IO_PENDING: 289 | raise SerialException("WriteFile failed (%r)" % ctypes.WinError()) 290 | if self._writeTimeout != 0: # if blocking (None) or w/ write timeout (>0) 291 | # Wait for the write to complete. 292 | #~ win32.WaitForSingleObject(self._overlappedWrite.hEvent, win32.INFINITE) 293 | err = win32.GetOverlappedResult(self.hComPort, self._overlappedWrite, ctypes.byref(n), True) 294 | if n.value != len(data): 295 | raise writeTimeoutError 296 | return n.value 297 | else: 298 | return 0 299 | 300 | def flush(self): 301 | """Flush of file like objects. In this case, wait until all data 302 | is written.""" 303 | while self.outWaiting(): 304 | time.sleep(0.05) 305 | # XXX could also use WaitCommEvent with mask EV_TXEMPTY, but it would 306 | # require overlapped IO and its also only possible to set a single mask 307 | # on the port--- 308 | 309 | def flushInput(self): 310 | """Clear input buffer, discarding all that is in the buffer.""" 311 | if not self.hComPort: raise portNotOpenError 312 | win32.PurgeComm(self.hComPort, win32.PURGE_RXCLEAR | win32.PURGE_RXABORT) 313 | 314 | def flushOutput(self): 315 | """Clear output buffer, aborting the current output and 316 | discarding all that is in the buffer.""" 317 | if not self.hComPort: raise portNotOpenError 318 | win32.PurgeComm(self.hComPort, win32.PURGE_TXCLEAR | win32.PURGE_TXABORT) 319 | 320 | def sendBreak(self, duration=0.25): 321 | """Send break condition. Timed, returns to idle state after given duration.""" 322 | if not self.hComPort: raise portNotOpenError 323 | import time 324 | win32.SetCommBreak(self.hComPort) 325 | time.sleep(duration) 326 | win32.ClearCommBreak(self.hComPort) 327 | 328 | def setBreak(self, level=1): 329 | """Set break: Controls TXD. When active, to transmitting is possible.""" 330 | if not self.hComPort: raise portNotOpenError 331 | if level: 332 | win32.SetCommBreak(self.hComPort) 333 | else: 334 | win32.ClearCommBreak(self.hComPort) 335 | 336 | def setRTS(self, level=1): 337 | """Set terminal status line: Request To Send""" 338 | # remember level for reconfigure 339 | if level: 340 | self._rtsState = win32.RTS_CONTROL_ENABLE 341 | else: 342 | self._rtsState = win32.RTS_CONTROL_DISABLE 343 | # also apply now if port is open 344 | if self.hComPort: 345 | if level: 346 | win32.EscapeCommFunction(self.hComPort, win32.SETRTS) 347 | else: 348 | win32.EscapeCommFunction(self.hComPort, win32.CLRRTS) 349 | 350 | def setDTR(self, level=1): 351 | """Set terminal status line: Data Terminal Ready""" 352 | # remember level for reconfigure 353 | if level: 354 | self._dtrState = win32.DTR_CONTROL_ENABLE 355 | else: 356 | self._dtrState = win32.DTR_CONTROL_DISABLE 357 | # also apply now if port is open 358 | if self.hComPort: 359 | if level: 360 | win32.EscapeCommFunction(self.hComPort, win32.SETDTR) 361 | else: 362 | win32.EscapeCommFunction(self.hComPort, win32.CLRDTR) 363 | 364 | def _GetCommModemStatus(self): 365 | stat = win32.DWORD() 366 | win32.GetCommModemStatus(self.hComPort, ctypes.byref(stat)) 367 | return stat.value 368 | 369 | def getCTS(self): 370 | """Read terminal status line: Clear To Send""" 371 | if not self.hComPort: raise portNotOpenError 372 | return win32.MS_CTS_ON & self._GetCommModemStatus() != 0 373 | 374 | def getDSR(self): 375 | """Read terminal status line: Data Set Ready""" 376 | if not self.hComPort: raise portNotOpenError 377 | return win32.MS_DSR_ON & self._GetCommModemStatus() != 0 378 | 379 | def getRI(self): 380 | """Read terminal status line: Ring Indicator""" 381 | if not self.hComPort: raise portNotOpenError 382 | return win32.MS_RING_ON & self._GetCommModemStatus() != 0 383 | 384 | def getCD(self): 385 | """Read terminal status line: Carrier Detect""" 386 | if not self.hComPort: raise portNotOpenError 387 | return win32.MS_RLSD_ON & self._GetCommModemStatus() != 0 388 | 389 | # - - platform specific - - - - 390 | 391 | def setBufferSize(self, rx_size=4096, tx_size=None): 392 | """\ 393 | Recommend a buffer size to the driver (device driver can ignore this 394 | vlaue). Must be called before the port is opended. 395 | """ 396 | if tx_size is None: tx_size = rx_size 397 | win32.SetupComm(self.hComPort, rx_size, tx_size) 398 | 399 | def setXON(self, level=True): 400 | """\ 401 | Manually control flow - when software flow control is enabled. 402 | This will send XON (true) and XOFF (false) to the other device. 403 | WARNING: this function is not portable to different platforms! 404 | """ 405 | if not self.hComPort: raise portNotOpenError 406 | if level: 407 | win32.EscapeCommFunction(self.hComPort, win32.SETXON) 408 | else: 409 | win32.EscapeCommFunction(self.hComPort, win32.SETXOFF) 410 | 411 | def outWaiting(self): 412 | """return how many characters the in the outgoing buffer""" 413 | flags = win32.DWORD() 414 | comstat = win32.COMSTAT() 415 | if not win32.ClearCommError(self.hComPort, ctypes.byref(flags), ctypes.byref(comstat)): 416 | raise SerialException('call to ClearCommError failed') 417 | return comstat.cbOutQue 418 | 419 | # functions useful for RS-485 adapters 420 | def setRtsToggle(self, rtsToggle): 421 | """Change RTS toggle control setting.""" 422 | self._rtsToggle = rtsToggle 423 | if self._isOpen: self._reconfigurePort() 424 | 425 | def getRtsToggle(self): 426 | """Get the current RTS toggle control setting.""" 427 | return self._rtsToggle 428 | 429 | rtsToggle = property(getRtsToggle, setRtsToggle, doc="RTS toggle control setting") 430 | 431 | 432 | # assemble Serial class with the platform specific implementation and the base 433 | # for file-like behavior. for Python 2.6 and newer, that provide the new I/O 434 | # library, derive from io.RawIOBase 435 | try: 436 | import io 437 | except ImportError: 438 | # classic version with our own file-like emulation 439 | class Serial(Win32Serial, FileLike): 440 | pass 441 | else: 442 | # io library present 443 | class Serial(Win32Serial, io.RawIOBase): 444 | pass 445 | 446 | 447 | # Nur Testfunktion!! 448 | if __name__ == '__main__': 449 | s = Serial(0) 450 | sys.stdout.write("%s\n" % s) 451 | 452 | s = Serial() 453 | sys.stdout.write("%s\n" % s) 454 | 455 | s.baudrate = 19200 456 | s.databits = 7 457 | s.close() 458 | s.port = 0 459 | s.open() 460 | sys.stdout.write("%s\n" % s) 461 | 462 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/sermsdos.py: -------------------------------------------------------------------------------- 1 | # sermsdos.py 2 | # 3 | # History: 4 | # 5 | # 3rd September 2002 Dave Haynes 6 | # 1. First defined 7 | # 8 | # Although this code should run under the latest versions of 9 | # Python, on DOS-based platforms such as Windows 95 and 98, 10 | # it has been specifically written to be compatible with 11 | # PyDOS, available at: 12 | # http://www.python.org/ftp/python/wpy/dos.html 13 | # 14 | # PyDOS is a stripped-down version of Python 1.5.2 for 15 | # DOS machines. Therefore, in making changes to this file, 16 | # please respect Python 1.5.2 syntax. In addition, please 17 | # limit the width of this file to 60 characters. 18 | # 19 | # Note also that the modules in PyDOS contain fewer members 20 | # than other versions, so we are restricted to using the 21 | # following: 22 | # 23 | # In module os: 24 | # ------------- 25 | # environ, chdir, getcwd, getpid, umask, fdopen, close, 26 | # dup, dup2, fstat, lseek, open, read, write, O_RDONLY, 27 | # O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_EXCL, O_TRUNC, 28 | # access, F_OK, R_OK, W_OK, X_OK, chmod, listdir, mkdir, 29 | # remove, rename, renames, rmdir, stat, unlink, utime, 30 | # execl, execle, execlp, execlpe, execvp, execvpe, _exit, 31 | # system. 32 | # 33 | # In module os.path: 34 | # ------------------ 35 | # curdir, pardir, sep, altsep, pathsep, defpath, linesep. 36 | # 37 | 38 | import os 39 | import sys 40 | import string 41 | import serial.serialutil 42 | 43 | BAUD_RATES = { 44 | 110: "11", 45 | 150: "15", 46 | 300: "30", 47 | 600: "60", 48 | 1200: "12", 49 | 2400: "24", 50 | 4800: "48", 51 | 9600: "96", 52 | 19200: "19"} 53 | 54 | (PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK, 55 | PARITY_SPACE) = (0, 1, 2, 3, 4) 56 | (STOPBITS_ONE, STOPBITS_ONEANDAHALF, 57 | STOPBITS_TWO) = (1, 1.5, 2) 58 | FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS = (5, 6, 7, 8) 59 | (RETURN_ERROR, RETURN_BUSY, RETURN_RETRY, RETURN_READY, 60 | RETURN_NONE) = ('E', 'B', 'P', 'R', 'N') 61 | portNotOpenError = ValueError('port not open') 62 | 63 | def device(portnum): 64 | return 'COM%d' % (portnum+1) 65 | 66 | class Serial(serialutil.FileLike): 67 | """ 68 | port: number of device; numbering starts at 69 | zero. if everything fails, the user can 70 | specify a device string, note that this 71 | isn't portable any more 72 | baudrate: baud rate 73 | bytesize: number of databits 74 | parity: enable parity checking 75 | stopbits: number of stopbits 76 | timeout: set a timeout (None for waiting forever) 77 | xonxoff: enable software flow control 78 | rtscts: enable RTS/CTS flow control 79 | retry: DOS retry mode 80 | """ 81 | def __init__(self, 82 | port, 83 | baudrate = 9600, 84 | bytesize = EIGHTBITS, 85 | parity = PARITY_NONE, 86 | stopbits = STOPBITS_ONE, 87 | timeout = None, 88 | xonxoff = 0, 89 | rtscts = 0, 90 | retry = RETURN_RETRY 91 | ): 92 | 93 | if type(port) == type(''): 94 | # strings are taken directly 95 | self.portstr = port 96 | else: 97 | # numbers are transformed to a string 98 | self.portstr = device(port+1) 99 | 100 | self.baud = BAUD_RATES[baudrate] 101 | self.bytesize = str(bytesize) 102 | 103 | if parity == PARITY_NONE: 104 | self.parity = 'N' 105 | elif parity == PARITY_EVEN: 106 | self.parity = 'E' 107 | elif parity == PARITY_ODD: 108 | self.parity = 'O' 109 | elif parity == PARITY_MARK: 110 | self.parity = 'M' 111 | elif parity == PARITY_SPACE: 112 | self.parity = 'S' 113 | 114 | self.stop = str(stopbits) 115 | self.retry = retry 116 | self.filename = "sermsdos.tmp" 117 | 118 | self._config(self.portstr, self.baud, self.parity, 119 | self.bytesize, self.stop, self.retry, self.filename) 120 | 121 | def __del__(self): 122 | self.close() 123 | 124 | def close(self): 125 | pass 126 | 127 | def _config(self, port, baud, parity, data, stop, retry, 128 | filename): 129 | comString = string.join(("MODE ", port, ":" 130 | , " BAUD= ", baud, " PARITY= ", parity 131 | , " DATA= ", data, " STOP= ", stop, " RETRY= ", 132 | retry, " > ", filename ), '') 133 | os.system(comString) 134 | 135 | def setBaudrate(self, baudrate): 136 | self._config(self.portstr, BAUD_RATES[baudrate], 137 | self.parity, self.bytesize, self.stop, self.retry, 138 | self.filename) 139 | 140 | def inWaiting(self): 141 | """returns the number of bytes waiting to be read""" 142 | raise NotImplementedError 143 | 144 | def read(self, num = 1): 145 | """Read num bytes from serial port""" 146 | handle = os.open(self.portstr, 147 | os.O_RDONLY | os.O_BINARY) 148 | rv = os.read(handle, num) 149 | os.close(handle) 150 | return rv 151 | 152 | def write(self, s): 153 | """Write string to serial port""" 154 | handle = os.open(self.portstr, 155 | os.O_WRONLY | os.O_BINARY) 156 | rv = os.write(handle, s) 157 | os.close(handle) 158 | return rv 159 | 160 | def flushInput(self): 161 | raise NotImplementedError 162 | 163 | def flushOutput(self): 164 | raise NotImplementedError 165 | 166 | def sendBreak(self): 167 | raise NotImplementedError 168 | 169 | def setRTS(self,level=1): 170 | """Set terminal status line""" 171 | raise NotImplementedError 172 | 173 | def setDTR(self,level=1): 174 | """Set terminal status line""" 175 | raise NotImplementedError 176 | 177 | def getCTS(self): 178 | """Eead terminal status line""" 179 | raise NotImplementedError 180 | 181 | def getDSR(self): 182 | """Eead terminal status line""" 183 | raise NotImplementedError 184 | 185 | def getRI(self): 186 | """Eead terminal status line""" 187 | raise NotImplementedError 188 | 189 | def getCD(self): 190 | """Eead terminal status line""" 191 | raise NotImplementedError 192 | 193 | def __repr__(self): 194 | return string.join(( ": ", self.portstr 195 | , self.baud, self.parity, self.bytesize, self.stop, 196 | self.retry , self.filename), ' ') 197 | 198 | if __name__ == '__main__': 199 | s = Serial(0) 200 | sys.stdio.write('%s %s\n' % (__name__, s)) 201 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/Snap!Files/Snap!Mobile/arduino/serial/tools/__init__.py -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/list_ports.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # portable serial port access with python 4 | # this is a wrapper module for different platform implementations of the 5 | # port enumeration feature 6 | # 7 | # (C) 2011-2013 Chris Liechti 8 | # this is distributed under a free software license, see license.txt 9 | 10 | """\ 11 | This module will provide a function called comports that returns an 12 | iterable (generator or list) that will enumerate available com ports. Note that 13 | on some systems non-existent ports may be listed. 14 | 15 | Additionally a grep function is supplied that can be used to search for ports 16 | based on their descriptions or hardware ID. 17 | """ 18 | 19 | import sys, os, re 20 | 21 | # chose an implementation, depending on os 22 | #~ if sys.platform == 'cli': 23 | #~ else: 24 | import os 25 | # chose an implementation, depending on os 26 | if os.name == 'nt': #sys.platform == 'win32': 27 | from serial.tools.list_ports_windows import * 28 | elif os.name == 'posix': 29 | from serial.tools.list_ports_posix import * 30 | #~ elif os.name == 'java': 31 | else: 32 | raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,)) 33 | 34 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 35 | 36 | def grep(regexp): 37 | """\ 38 | Search for ports using a regular expression. Port name, description and 39 | hardware ID are searched. The function returns an iterable that returns the 40 | same tuples as comport() would do. 41 | """ 42 | r = re.compile(regexp, re.I) 43 | for port, desc, hwid in comports(): 44 | if r.search(port) or r.search(desc) or r.search(hwid): 45 | yield port, desc, hwid 46 | 47 | 48 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 49 | def main(): 50 | import optparse 51 | 52 | parser = optparse.OptionParser( 53 | usage = "%prog [options] []", 54 | description = "Miniterm - A simple terminal program for the serial port." 55 | ) 56 | 57 | parser.add_option("--debug", 58 | help="print debug messages and tracebacks (development mode)", 59 | dest="debug", 60 | default=False, 61 | action='store_true') 62 | 63 | parser.add_option("-v", "--verbose", 64 | help="show more messages (can be given multiple times)", 65 | dest="verbose", 66 | default=1, 67 | action='count') 68 | 69 | parser.add_option("-q", "--quiet", 70 | help="suppress all messages", 71 | dest="verbose", 72 | action='store_const', 73 | const=0) 74 | 75 | (options, args) = parser.parse_args() 76 | 77 | 78 | hits = 0 79 | # get iteraror w/ or w/o filter 80 | if args: 81 | if len(args) > 1: 82 | parser.error('more than one regexp not supported') 83 | print "Filtered list with regexp: %r" % (args[0],) 84 | iterator = sorted(grep(args[0])) 85 | else: 86 | iterator = sorted(comports()) 87 | # list them 88 | for port, desc, hwid in iterator: 89 | print("%-20s" % (port,)) 90 | if options.verbose > 1: 91 | print(" desc: %s" % (desc,)) 92 | print(" hwid: %s" % (hwid,)) 93 | hits += 1 94 | if options.verbose: 95 | if hits: 96 | print("%d ports found" % (hits,)) 97 | else: 98 | print("no ports found") 99 | 100 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 101 | # test 102 | if __name__ == '__main__': 103 | main() 104 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/list_ports_linux.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # portable serial port access with python 4 | # 5 | # This is a module that gathers a list of serial ports including details on 6 | # GNU/Linux systems 7 | # 8 | # (C) 2011-2013 Chris Liechti 9 | # this is distributed under a free software license, see license.txt 10 | 11 | import glob 12 | import sys 13 | import os 14 | import re 15 | 16 | try: 17 | import subprocess 18 | except ImportError: 19 | def popen(argv): 20 | try: 21 | si, so = os.popen4(' '.join(argv)) 22 | return so.read().strip() 23 | except: 24 | raise IOError('lsusb failed') 25 | else: 26 | def popen(argv): 27 | try: 28 | return subprocess.check_output(argv, stderr=subprocess.STDOUT).strip() 29 | except: 30 | raise IOError('lsusb failed') 31 | 32 | 33 | # The comports function is expected to return an iterable that yields tuples of 34 | # 3 strings: port name, human readable description and a hardware ID. 35 | # 36 | # as currently no method is known to get the second two strings easily, they 37 | # are currently just identical to the port name. 38 | 39 | # try to detect the OS so that a device can be selected... 40 | plat = sys.platform.lower() 41 | 42 | def read_line(filename): 43 | """help function to read a single line from a file. returns none""" 44 | try: 45 | f = open(filename) 46 | line = f.readline().strip() 47 | f.close() 48 | return line 49 | except IOError: 50 | return None 51 | 52 | def re_group(regexp, text): 53 | """search for regexp in text, return 1st group on match""" 54 | if sys.version < '3': 55 | m = re.search(regexp, text) 56 | else: 57 | # text is bytes-like 58 | m = re.search(regexp, text.decode('ascii', 'replace')) 59 | if m: return m.group(1) 60 | 61 | 62 | # try to extract descriptions from sysfs. this was done by experimenting, 63 | # no guarantee that it works for all devices or in the future... 64 | 65 | def usb_sysfs_hw_string(sysfs_path): 66 | """given a path to a usb device in sysfs, return a string describing it""" 67 | bus, dev = os.path.basename(os.path.realpath(sysfs_path)).split('-') 68 | snr = read_line(sysfs_path+'/serial') 69 | if snr: 70 | snr_txt = ' SNR=%s' % (snr,) 71 | else: 72 | snr_txt = '' 73 | return 'USB VID:PID=%s:%s%s' % ( 74 | read_line(sysfs_path+'/idVendor'), 75 | read_line(sysfs_path+'/idProduct'), 76 | snr_txt 77 | ) 78 | 79 | def usb_lsusb_string(sysfs_path): 80 | base = os.path.basename(os.path.realpath(sysfs_path)) 81 | bus = base.split('-')[0] 82 | try: 83 | dev = int(read_line(os.path.join(sysfs_path, 'devnum'))) 84 | desc = popen(['lsusb', '-v', '-s', '%s:%s' % (bus, dev)]) 85 | # descriptions from device 86 | iManufacturer = re_group('iManufacturer\s+\w+ (.+)', desc) 87 | iProduct = re_group('iProduct\s+\w+ (.+)', desc) 88 | iSerial = re_group('iSerial\s+\w+ (.+)', desc) or '' 89 | # descriptions from kernel 90 | idVendor = re_group('idVendor\s+0x\w+ (.+)', desc) 91 | idProduct = re_group('idProduct\s+0x\w+ (.+)', desc) 92 | # create descriptions. prefer text from device, fall back to the others 93 | return '%s %s %s' % (iManufacturer or idVendor, iProduct or idProduct, iSerial) 94 | except IOError: 95 | return base 96 | 97 | def describe(device): 98 | """\ 99 | Get a human readable description. 100 | For USB-Serial devices try to run lsusb to get a human readable description. 101 | For USB-CDC devices read the description from sysfs. 102 | """ 103 | base = os.path.basename(device) 104 | # USB-Serial devices 105 | sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) 106 | if os.path.exists(sys_dev_path): 107 | sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) 108 | return usb_lsusb_string(sys_usb) 109 | # USB-CDC devices 110 | sys_dev_path = '/sys/class/tty/%s/device/interface' % (base,) 111 | if os.path.exists(sys_dev_path): 112 | return read_line(sys_dev_path) 113 | return base 114 | 115 | def hwinfo(device): 116 | """Try to get a HW identification using sysfs""" 117 | base = os.path.basename(device) 118 | if os.path.exists('/sys/class/tty/%s/device' % (base,)): 119 | # PCI based devices 120 | sys_id_path = '/sys/class/tty/%s/device/id' % (base,) 121 | if os.path.exists(sys_id_path): 122 | return read_line(sys_id_path) 123 | # USB-Serial devices 124 | sys_dev_path = '/sys/class/tty/%s/device/driver/%s' % (base, base) 125 | if os.path.exists(sys_dev_path): 126 | sys_usb = os.path.dirname(os.path.dirname(os.path.realpath(sys_dev_path))) 127 | return usb_sysfs_hw_string(sys_usb) 128 | # USB-CDC devices 129 | if base.startswith('ttyACM'): 130 | sys_dev_path = '/sys/class/tty/%s/device' % (base,) 131 | if os.path.exists(sys_dev_path): 132 | return usb_sysfs_hw_string(sys_dev_path + '/..') 133 | return 'n/a' # XXX directly remove these from the list? 134 | 135 | def comports(): 136 | devices = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') 137 | return [(d, describe(d), hwinfo(d)) for d in devices] 138 | 139 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 140 | # test 141 | if __name__ == '__main__': 142 | for port, desc, hwid in sorted(comports()): 143 | print "%s: %s [%s]" % (port, desc, hwid) 144 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/list_ports_osx.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # portable serial port access with python 4 | # 5 | # This is a module that gathers a list of serial ports including details on OSX 6 | # 7 | # code originally from https://github.com/makerbot/pyserial/tree/master/serial/tools 8 | # with contributions from cibomahto, dgs3, FarMcKon, tedbrandston 9 | # and modifications by cliechti 10 | # 11 | # this is distributed under a free software license, see license.txt 12 | 13 | 14 | 15 | # List all of the callout devices in OS/X by querying IOKit. 16 | 17 | # See the following for a reference of how to do this: 18 | # http://developer.apple.com/library/mac/#documentation/DeviceDrivers/Conceptual/WorkingWSerial/WWSerial_SerialDevs/SerialDevices.html#//apple_ref/doc/uid/TP30000384-CIHGEAFD 19 | 20 | # More help from darwin_hid.py 21 | 22 | # Also see the 'IORegistryExplorer' for an idea of what we are actually searching 23 | 24 | import ctypes 25 | from ctypes import util 26 | import re 27 | 28 | iokit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('IOKit')) 29 | cf = ctypes.cdll.LoadLibrary(ctypes.util.find_library('CoreFoundation')) 30 | 31 | kIOMasterPortDefault = ctypes.c_void_p.in_dll(iokit, "kIOMasterPortDefault") 32 | kCFAllocatorDefault = ctypes.c_void_p.in_dll(cf, "kCFAllocatorDefault") 33 | 34 | kCFStringEncodingMacRoman = 0 35 | 36 | iokit.IOServiceMatching.restype = ctypes.c_void_p 37 | 38 | iokit.IOServiceGetMatchingServices.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] 39 | iokit.IOServiceGetMatchingServices.restype = ctypes.c_void_p 40 | 41 | iokit.IORegistryEntryGetParentEntry.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] 42 | 43 | iokit.IORegistryEntryCreateCFProperty.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint32] 44 | iokit.IORegistryEntryCreateCFProperty.restype = ctypes.c_void_p 45 | 46 | iokit.IORegistryEntryGetPath.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] 47 | iokit.IORegistryEntryGetPath.restype = ctypes.c_void_p 48 | 49 | iokit.IORegistryEntryGetName.argtypes = [ctypes.c_void_p, ctypes.c_void_p] 50 | iokit.IORegistryEntryGetName.restype = ctypes.c_void_p 51 | 52 | iokit.IOObjectGetClass.argtypes = [ctypes.c_void_p, ctypes.c_void_p] 53 | iokit.IOObjectGetClass.restype = ctypes.c_void_p 54 | 55 | iokit.IOObjectRelease.argtypes = [ctypes.c_void_p] 56 | 57 | 58 | cf.CFStringCreateWithCString.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int32] 59 | cf.CFStringCreateWithCString.restype = ctypes.c_void_p 60 | 61 | cf.CFStringGetCStringPtr.argtypes = [ctypes.c_void_p, ctypes.c_uint32] 62 | cf.CFStringGetCStringPtr.restype = ctypes.c_char_p 63 | 64 | cf.CFNumberGetValue.argtypes = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_void_p] 65 | cf.CFNumberGetValue.restype = ctypes.c_void_p 66 | 67 | def get_string_property(device_t, property): 68 | """ Search the given device for the specified string property 69 | 70 | @param device_t Device to search 71 | @param property String to search for. 72 | @return Python string containing the value, or None if not found. 73 | """ 74 | key = cf.CFStringCreateWithCString( 75 | kCFAllocatorDefault, 76 | property.encode("mac_roman"), 77 | kCFStringEncodingMacRoman 78 | ) 79 | 80 | CFContainer = iokit.IORegistryEntryCreateCFProperty( 81 | device_t, 82 | key, 83 | kCFAllocatorDefault, 84 | 0 85 | ); 86 | 87 | output = None 88 | 89 | if CFContainer: 90 | output = cf.CFStringGetCStringPtr(CFContainer, 0) 91 | 92 | return output 93 | 94 | def get_int_property(device_t, property): 95 | """ Search the given device for the specified string property 96 | 97 | @param device_t Device to search 98 | @param property String to search for. 99 | @return Python string containing the value, or None if not found. 100 | """ 101 | key = cf.CFStringCreateWithCString( 102 | kCFAllocatorDefault, 103 | property.encode("mac_roman"), 104 | kCFStringEncodingMacRoman 105 | ) 106 | 107 | CFContainer = iokit.IORegistryEntryCreateCFProperty( 108 | device_t, 109 | key, 110 | kCFAllocatorDefault, 111 | 0 112 | ); 113 | 114 | number = ctypes.c_uint16() 115 | 116 | if CFContainer: 117 | output = cf.CFNumberGetValue(CFContainer, 2, ctypes.byref(number)) 118 | 119 | return number.value 120 | 121 | def IORegistryEntryGetName(device): 122 | pathname = ctypes.create_string_buffer(100) # TODO: Is this ok? 123 | iokit.IOObjectGetClass( 124 | device, 125 | ctypes.byref(pathname) 126 | ) 127 | 128 | return pathname.value 129 | 130 | def GetParentDeviceByType(device, parent_type): 131 | """ Find the first parent of a device that implements the parent_type 132 | @param IOService Service to inspect 133 | @return Pointer to the parent type, or None if it was not found. 134 | """ 135 | # First, try to walk up the IOService tree to find a parent of this device that is a IOUSBDevice. 136 | while IORegistryEntryGetName(device) != parent_type: 137 | parent = ctypes.c_void_p() 138 | response = iokit.IORegistryEntryGetParentEntry( 139 | device, 140 | "IOService".encode("mac_roman"), 141 | ctypes.byref(parent) 142 | ) 143 | 144 | # If we weren't able to find a parent for the device, we're done. 145 | if response != 0: 146 | return None 147 | 148 | device = parent 149 | 150 | return device 151 | 152 | def GetIOServicesByType(service_type): 153 | """ 154 | """ 155 | serial_port_iterator = ctypes.c_void_p() 156 | 157 | response = iokit.IOServiceGetMatchingServices( 158 | kIOMasterPortDefault, 159 | iokit.IOServiceMatching(service_type), 160 | ctypes.byref(serial_port_iterator) 161 | ) 162 | 163 | services = [] 164 | while iokit.IOIteratorIsValid(serial_port_iterator): 165 | service = iokit.IOIteratorNext(serial_port_iterator) 166 | if not service: 167 | break 168 | services.append(service) 169 | 170 | iokit.IOObjectRelease(serial_port_iterator) 171 | 172 | return services 173 | 174 | def comports(): 175 | # Scan for all iokit serial ports 176 | services = GetIOServicesByType('IOSerialBSDClient') 177 | 178 | ports = [] 179 | for service in services: 180 | info = [] 181 | 182 | # First, add the callout device file. 183 | info.append(get_string_property(service, "IOCalloutDevice")) 184 | 185 | # If the serial port is implemented by a 186 | usb_device = GetParentDeviceByType(service, "IOUSBDevice") 187 | if usb_device != None: 188 | info.append(get_string_property(usb_device, "USB Product Name")) 189 | 190 | info.append( 191 | "USB VID:PID=%x:%x SNR=%s"%( 192 | get_int_property(usb_device, "idVendor"), 193 | get_int_property(usb_device, "idProduct"), 194 | get_string_property(usb_device, "USB Serial Number")) 195 | ) 196 | else: 197 | info.append('n/a') 198 | info.append('n/a') 199 | 200 | ports.append(info) 201 | 202 | return ports 203 | 204 | # test 205 | if __name__ == '__main__': 206 | for port, desc, hwid in sorted(comports()): 207 | print "%s: %s [%s]" % (port, desc, hwid) 208 | 209 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/list_ports_posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # portable serial port access with python 4 | 5 | # This is a module that gathers a list of serial ports on POSIXy systems. 6 | # For some specific implementations, see also list_ports_linux, list_ports_osx 7 | # 8 | # this is a wrapper module for different platform implementations of the 9 | # port enumeration feature 10 | # 11 | # (C) 2011-2013 Chris Liechti 12 | # this is distributed under a free software license, see license.txt 13 | 14 | """\ 15 | The ``comports`` function is expected to return an iterable that yields tuples 16 | of 3 strings: port name, human readable description and a hardware ID. 17 | 18 | As currently no method is known to get the second two strings easily, they are 19 | currently just identical to the port name. 20 | """ 21 | 22 | import glob 23 | import sys 24 | import os 25 | 26 | # try to detect the OS so that a device can be selected... 27 | plat = sys.platform.lower() 28 | 29 | if plat[:5] == 'linux': # Linux (confirmed) 30 | from serial.tools.list_ports_linux import comports 31 | 32 | elif plat == 'cygwin': # cygwin/win32 33 | def comports(): 34 | devices = glob.glob('/dev/com*') 35 | return [(d, d, d) for d in devices] 36 | 37 | elif plat[:7] == 'openbsd': # OpenBSD 38 | def comports(): 39 | devices = glob.glob('/dev/cua*') 40 | return [(d, d, d) for d in devices] 41 | 42 | elif plat[:3] == 'bsd' or \ 43 | plat[:7] == 'freebsd': 44 | 45 | def comports(): 46 | devices = glob.glob('/dev/cuad*') 47 | return [(d, d, d) for d in devices] 48 | 49 | elif plat[:6] == 'darwin': # OS X (confirmed) 50 | from serial.tools.list_ports_osx import comports 51 | 52 | elif plat[:6] == 'netbsd': # NetBSD 53 | def comports(): 54 | """scan for available ports. return a list of device names.""" 55 | devices = glob.glob('/dev/dty*') 56 | return [(d, d, d) for d in devices] 57 | 58 | elif plat[:4] == 'irix': # IRIX 59 | def comports(): 60 | """scan for available ports. return a list of device names.""" 61 | devices = glob.glob('/dev/ttyf*') 62 | return [(d, d, d) for d in devices] 63 | 64 | elif plat[:2] == 'hp': # HP-UX (not tested) 65 | def comports(): 66 | """scan for available ports. return a list of device names.""" 67 | devices = glob.glob('/dev/tty*p0') 68 | return [(d, d, d) for d in devices] 69 | 70 | elif plat[:5] == 'sunos': # Solaris/SunOS 71 | def comports(): 72 | """scan for available ports. return a list of device names.""" 73 | devices = glob.glob('/dev/tty*c') 74 | return [(d, d, d) for d in devices] 75 | 76 | elif plat[:3] == 'aix': # AIX 77 | def comports(): 78 | """scan for available ports. return a list of device names.""" 79 | devices = glob.glob('/dev/tty*') 80 | return [(d, d, d) for d in devices] 81 | 82 | else: 83 | # platform detection has failed... 84 | sys.stderr.write("""\ 85 | don't know how to enumerate ttys on this system. 86 | ! I you know how the serial ports are named send this information to 87 | ! the author of this module: 88 | 89 | sys.platform = %r 90 | os.name = %r 91 | pySerial version = %s 92 | 93 | also add the naming scheme of the serial ports and with a bit luck you can get 94 | this module running... 95 | """ % (sys.platform, os.name, serial.VERSION)) 96 | raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,)) 97 | 98 | # test 99 | if __name__ == '__main__': 100 | for port, desc, hwid in sorted(comports()): 101 | print "%s: %s [%s]" % (port, desc, hwid) 102 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/tools/list_ports_windows.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import re 3 | 4 | def ValidHandle(value, func, arguments): 5 | if value == 0: 6 | raise ctypes.WinError() 7 | return value 8 | 9 | import serial 10 | from serial.win32 import ULONG_PTR, is_64bit 11 | from ctypes.wintypes import HANDLE 12 | from ctypes.wintypes import BOOL 13 | from ctypes.wintypes import HWND 14 | from ctypes.wintypes import DWORD 15 | from ctypes.wintypes import WORD 16 | from ctypes.wintypes import LONG 17 | from ctypes.wintypes import ULONG 18 | from ctypes.wintypes import LPCSTR 19 | from ctypes.wintypes import HKEY 20 | from ctypes.wintypes import BYTE 21 | 22 | NULL = 0 23 | HDEVINFO = ctypes.c_void_p 24 | PCTSTR = ctypes.c_char_p 25 | PTSTR = ctypes.c_void_p 26 | CHAR = ctypes.c_char 27 | LPDWORD = PDWORD = ctypes.POINTER(DWORD) 28 | #~ LPBYTE = PBYTE = ctypes.POINTER(BYTE) 29 | LPBYTE = PBYTE = ctypes.c_void_p # XXX avoids error about types 30 | 31 | ACCESS_MASK = DWORD 32 | REGSAM = ACCESS_MASK 33 | 34 | 35 | def byte_buffer(length): 36 | """Get a buffer for a string""" 37 | return (BYTE*length)() 38 | 39 | def string(buffer): 40 | s = [] 41 | for c in buffer: 42 | if c == 0: break 43 | s.append(chr(c & 0xff)) # "& 0xff": hack to convert signed to unsigned 44 | return ''.join(s) 45 | 46 | 47 | class GUID(ctypes.Structure): 48 | _fields_ = [ 49 | ('Data1', DWORD), 50 | ('Data2', WORD), 51 | ('Data3', WORD), 52 | ('Data4', BYTE*8), 53 | ] 54 | def __str__(self): 55 | return "{%08x-%04x-%04x-%s-%s}" % ( 56 | self.Data1, 57 | self.Data2, 58 | self.Data3, 59 | ''.join(["%02x" % d for d in self.Data4[:2]]), 60 | ''.join(["%02x" % d for d in self.Data4[2:]]), 61 | ) 62 | 63 | class SP_DEVINFO_DATA(ctypes.Structure): 64 | _fields_ = [ 65 | ('cbSize', DWORD), 66 | ('ClassGuid', GUID), 67 | ('DevInst', DWORD), 68 | ('Reserved', ULONG_PTR), 69 | ] 70 | def __str__(self): 71 | return "ClassGuid:%s DevInst:%s" % (self.ClassGuid, self.DevInst) 72 | PSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA) 73 | 74 | PSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p 75 | 76 | setupapi = ctypes.windll.LoadLibrary("setupapi") 77 | SetupDiDestroyDeviceInfoList = setupapi.SetupDiDestroyDeviceInfoList 78 | SetupDiDestroyDeviceInfoList.argtypes = [HDEVINFO] 79 | SetupDiDestroyDeviceInfoList.restype = BOOL 80 | 81 | SetupDiClassGuidsFromName = setupapi.SetupDiClassGuidsFromNameA 82 | SetupDiClassGuidsFromName.argtypes = [PCTSTR, ctypes.POINTER(GUID), DWORD, PDWORD] 83 | SetupDiClassGuidsFromName.restype = BOOL 84 | 85 | SetupDiEnumDeviceInfo = setupapi.SetupDiEnumDeviceInfo 86 | SetupDiEnumDeviceInfo.argtypes = [HDEVINFO, DWORD, PSP_DEVINFO_DATA] 87 | SetupDiEnumDeviceInfo.restype = BOOL 88 | 89 | SetupDiGetClassDevs = setupapi.SetupDiGetClassDevsA 90 | SetupDiGetClassDevs.argtypes = [ctypes.POINTER(GUID), PCTSTR, HWND, DWORD] 91 | SetupDiGetClassDevs.restype = HDEVINFO 92 | SetupDiGetClassDevs.errcheck = ValidHandle 93 | 94 | SetupDiGetDeviceRegistryProperty = setupapi.SetupDiGetDeviceRegistryPropertyA 95 | SetupDiGetDeviceRegistryProperty.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD] 96 | SetupDiGetDeviceRegistryProperty.restype = BOOL 97 | 98 | SetupDiGetDeviceInstanceId = setupapi.SetupDiGetDeviceInstanceIdA 99 | SetupDiGetDeviceInstanceId.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, PTSTR, DWORD, PDWORD] 100 | SetupDiGetDeviceInstanceId.restype = BOOL 101 | 102 | SetupDiOpenDevRegKey = setupapi.SetupDiOpenDevRegKey 103 | SetupDiOpenDevRegKey.argtypes = [HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM] 104 | SetupDiOpenDevRegKey.restype = HKEY 105 | 106 | advapi32 = ctypes.windll.LoadLibrary("Advapi32") 107 | RegCloseKey = advapi32.RegCloseKey 108 | RegCloseKey.argtypes = [HKEY] 109 | RegCloseKey.restype = LONG 110 | 111 | RegQueryValueEx = advapi32.RegQueryValueExA 112 | RegQueryValueEx.argtypes = [HKEY, LPCSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD] 113 | RegQueryValueEx.restype = LONG 114 | 115 | 116 | DIGCF_PRESENT = 2 117 | DIGCF_DEVICEINTERFACE = 16 118 | INVALID_HANDLE_VALUE = 0 119 | ERROR_INSUFFICIENT_BUFFER = 122 120 | SPDRP_HARDWAREID = 1 121 | SPDRP_FRIENDLYNAME = 12 122 | DICS_FLAG_GLOBAL = 1 123 | DIREG_DEV = 0x00000001 124 | KEY_READ = 0x20019 125 | 126 | # workaround for compatibility between Python 2.x and 3.x 127 | Ports = serial.to_bytes([80, 111, 114, 116, 115]) # "Ports" 128 | PortName = serial.to_bytes([80, 111, 114, 116, 78, 97, 109, 101]) # "PortName" 129 | 130 | def comports(): 131 | GUIDs = (GUID*8)() # so far only seen one used, so hope 8 are enough... 132 | guids_size = DWORD() 133 | if not SetupDiClassGuidsFromName( 134 | Ports, 135 | GUIDs, 136 | ctypes.sizeof(GUIDs), 137 | ctypes.byref(guids_size)): 138 | raise ctypes.WinError() 139 | 140 | # repeat for all possible GUIDs 141 | for index in range(guids_size.value): 142 | g_hdi = SetupDiGetClassDevs( 143 | ctypes.byref(GUIDs[index]), 144 | None, 145 | NULL, 146 | DIGCF_PRESENT) # was DIGCF_PRESENT|DIGCF_DEVICEINTERFACE which misses CDC ports 147 | 148 | devinfo = SP_DEVINFO_DATA() 149 | devinfo.cbSize = ctypes.sizeof(devinfo) 150 | index = 0 151 | while SetupDiEnumDeviceInfo(g_hdi, index, ctypes.byref(devinfo)): 152 | index += 1 153 | 154 | # get the real com port name 155 | hkey = SetupDiOpenDevRegKey( 156 | g_hdi, 157 | ctypes.byref(devinfo), 158 | DICS_FLAG_GLOBAL, 159 | 0, 160 | DIREG_DEV, # DIREG_DRV for SW info 161 | KEY_READ) 162 | port_name_buffer = byte_buffer(250) 163 | port_name_length = ULONG(ctypes.sizeof(port_name_buffer)) 164 | RegQueryValueEx( 165 | hkey, 166 | PortName, 167 | None, 168 | None, 169 | ctypes.byref(port_name_buffer), 170 | ctypes.byref(port_name_length)) 171 | RegCloseKey(hkey) 172 | 173 | # unfortunately does this method also include parallel ports. 174 | # we could check for names starting with COM or just exclude LPT 175 | # and hope that other "unknown" names are serial ports... 176 | if string(port_name_buffer).startswith('LPT'): 177 | continue 178 | 179 | # hardware ID 180 | szHardwareID = byte_buffer(250) 181 | # try to get ID that includes serial number 182 | if not SetupDiGetDeviceInstanceId( 183 | g_hdi, 184 | ctypes.byref(devinfo), 185 | ctypes.byref(szHardwareID), 186 | ctypes.sizeof(szHardwareID) - 1, 187 | None): 188 | # fall back to more generic hardware ID if that would fail 189 | if not SetupDiGetDeviceRegistryProperty( 190 | g_hdi, 191 | ctypes.byref(devinfo), 192 | SPDRP_HARDWAREID, 193 | None, 194 | ctypes.byref(szHardwareID), 195 | ctypes.sizeof(szHardwareID) - 1, 196 | None): 197 | # Ignore ERROR_INSUFFICIENT_BUFFER 198 | if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: 199 | raise ctypes.WinError() 200 | # stringify 201 | szHardwareID_str = string(szHardwareID) 202 | 203 | # in case of USB, make a more readable string, similar to that form 204 | # that we also generate on other platforms 205 | if szHardwareID_str.startswith('USB'): 206 | m = re.search(r'VID_([0-9a-f]{4})&PID_([0-9a-f]{4})(\\(\w+))?', szHardwareID_str, re.I) 207 | if m: 208 | if m.group(4): 209 | szHardwareID_str = 'USB VID:PID=%s:%s SNR=%s' % (m.group(1), m.group(2), m.group(4)) 210 | else: 211 | szHardwareID_str = 'USB VID:PID=%s:%s' % (m.group(1), m.group(2)) 212 | 213 | # friendly name 214 | szFriendlyName = byte_buffer(250) 215 | if not SetupDiGetDeviceRegistryProperty( 216 | g_hdi, 217 | ctypes.byref(devinfo), 218 | SPDRP_FRIENDLYNAME, 219 | #~ SPDRP_DEVICEDESC, 220 | None, 221 | ctypes.byref(szFriendlyName), 222 | ctypes.sizeof(szFriendlyName) - 1, 223 | None): 224 | # Ignore ERROR_INSUFFICIENT_BUFFER 225 | #~ if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER: 226 | #~ raise IOError("failed to get details for %s (%s)" % (devinfo, szHardwareID.value)) 227 | # ignore errors and still include the port in the list, friendly name will be same as port name 228 | yield string(port_name_buffer), 'n/a', szHardwareID_str 229 | else: 230 | yield string(port_name_buffer), string(szFriendlyName), szHardwareID_str 231 | 232 | SetupDiDestroyDeviceInfoList(g_hdi) 233 | 234 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 235 | # test 236 | if __name__ == '__main__': 237 | import serial 238 | 239 | for port, desc, hwid in sorted(comports()): 240 | print "%s: %s [%s]" % (port, desc, hwid) 241 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/urlhandler/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/Snap!Files/Snap!Mobile/arduino/serial/urlhandler/__init__.py -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/urlhandler/protocol_hwgrep.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # 3 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 4 | # see __init__.py 5 | # 6 | # This module implements a special URL handler that uses the port listing to 7 | # find ports by searching the string descriptions. 8 | # 9 | # (C) 2011 Chris Liechti 10 | # this is distributed under a free software license, see license.txt 11 | # 12 | # URL format: hwgrep://regexp 13 | 14 | import serial 15 | import serial.tools.list_ports 16 | 17 | class Serial(serial.Serial): 18 | """Just inherit the native Serial port implementation and patch the open function.""" 19 | 20 | def setPort(self, value): 21 | """translate port name before storing it""" 22 | if isinstance(value, basestring) and value.startswith('hwgrep://'): 23 | serial.Serial.setPort(self, self.fromURL(value)) 24 | else: 25 | serial.Serial.setPort(self, value) 26 | 27 | def fromURL(self, url): 28 | """extract host and port from an URL string""" 29 | if url.lower().startswith("hwgrep://"): url = url[9:] 30 | # use a for loop to get the 1st element from the generator 31 | for port, desc, hwid in serial.tools.list_ports.grep(url): 32 | return port 33 | else: 34 | raise serial.SerialException('no ports found matching regexp %r' % (url,)) 35 | 36 | # override property 37 | port = property(serial.Serial.getPort, setPort, doc="Port setting") 38 | 39 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 40 | if __name__ == '__main__': 41 | #~ s = Serial('hwgrep://ttyS0') 42 | s = Serial(None) 43 | s.port = 'hwgrep://ttyS0' 44 | print s 45 | 46 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/urlhandler/protocol_loop.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # 3 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 4 | # see __init__.py 5 | # 6 | # This module implements a loop back connection receiving itself what it sent. 7 | # 8 | # The purpose of this module is.. well... You can run the unit tests with it. 9 | # and it was so easy to implement ;-) 10 | # 11 | # (C) 2001-2011 Chris Liechti 12 | # this is distributed under a free software license, see license.txt 13 | # 14 | # URL format: loop://[option[/option...]] 15 | # options: 16 | # - "debug" print diagnostic messages 17 | 18 | from serial.serialutil import * 19 | import threading 20 | import time 21 | import logging 22 | 23 | # map log level names to constants. used in fromURL() 24 | LOGGER_LEVELS = { 25 | 'debug': logging.DEBUG, 26 | 'info': logging.INFO, 27 | 'warning': logging.WARNING, 28 | 'error': logging.ERROR, 29 | } 30 | 31 | 32 | class LoopbackSerial(SerialBase): 33 | """Serial port implementation that simulates a loop back connection in plain software.""" 34 | 35 | BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 36 | 9600, 19200, 38400, 57600, 115200) 37 | 38 | def open(self): 39 | """Open port with current settings. This may throw a SerialException 40 | if the port cannot be opened.""" 41 | if self._isOpen: 42 | raise SerialException("Port is already open.") 43 | self.logger = None 44 | self.buffer_lock = threading.Lock() 45 | self.loop_buffer = bytearray() 46 | self.cts = False 47 | self.dsr = False 48 | 49 | if self._port is None: 50 | raise SerialException("Port must be configured before it can be used.") 51 | # not that there is anything to open, but the function applies the 52 | # options found in the URL 53 | self.fromURL(self.port) 54 | 55 | # not that there anything to configure... 56 | self._reconfigurePort() 57 | # all things set up get, now a clean start 58 | self._isOpen = True 59 | if not self._rtscts: 60 | self.setRTS(True) 61 | self.setDTR(True) 62 | self.flushInput() 63 | self.flushOutput() 64 | 65 | def _reconfigurePort(self): 66 | """Set communication parameters on opened port. for the loop:// 67 | protocol all settings are ignored!""" 68 | # not that's it of any real use, but it helps in the unit tests 69 | if not isinstance(self._baudrate, (int, long)) or not 0 < self._baudrate < 2**32: 70 | raise ValueError("invalid baudrate: %r" % (self._baudrate)) 71 | if self.logger: 72 | self.logger.info('_reconfigurePort()') 73 | 74 | def close(self): 75 | """Close port""" 76 | if self._isOpen: 77 | self._isOpen = False 78 | # in case of quick reconnects, give the server some time 79 | time.sleep(0.3) 80 | 81 | def makeDeviceName(self, port): 82 | raise SerialException("there is no sensible way to turn numbers into URLs") 83 | 84 | def fromURL(self, url): 85 | """extract host and port from an URL string""" 86 | if url.lower().startswith("loop://"): url = url[7:] 87 | try: 88 | # process options now, directly altering self 89 | for option in url.split('/'): 90 | if '=' in option: 91 | option, value = option.split('=', 1) 92 | else: 93 | value = None 94 | if not option: 95 | pass 96 | elif option == 'logging': 97 | logging.basicConfig() # XXX is that good to call it here? 98 | self.logger = logging.getLogger('pySerial.loop') 99 | self.logger.setLevel(LOGGER_LEVELS[value]) 100 | self.logger.debug('enabled logging') 101 | else: 102 | raise ValueError('unknown option: %r' % (option,)) 103 | except ValueError, e: 104 | raise SerialException('expected a string in the form "[loop://][option[/option...]]": %s' % e) 105 | 106 | # - - - - - - - - - - - - - - - - - - - - - - - - 107 | 108 | def inWaiting(self): 109 | """Return the number of characters currently in the input buffer.""" 110 | if not self._isOpen: raise portNotOpenError 111 | if self.logger: 112 | # attention the logged value can differ from return value in 113 | # threaded environments... 114 | self.logger.debug('inWaiting() -> %d' % (len(self.loop_buffer),)) 115 | return len(self.loop_buffer) 116 | 117 | def read(self, size=1): 118 | """Read size bytes from the serial port. If a timeout is set it may 119 | return less characters as requested. With no timeout it will block 120 | until the requested number of bytes is read.""" 121 | if not self._isOpen: raise portNotOpenError 122 | if self._timeout is not None: 123 | timeout = time.time() + self._timeout 124 | else: 125 | timeout = None 126 | data = bytearray() 127 | while size > 0: 128 | self.buffer_lock.acquire() 129 | try: 130 | block = to_bytes(self.loop_buffer[:size]) 131 | del self.loop_buffer[:size] 132 | finally: 133 | self.buffer_lock.release() 134 | data += block 135 | size -= len(block) 136 | # check for timeout now, after data has been read. 137 | # useful for timeout = 0 (non blocking) read 138 | if timeout and time.time() > timeout: 139 | break 140 | return bytes(data) 141 | 142 | def write(self, data): 143 | """Output the given string over the serial port. Can block if the 144 | connection is blocked. May raise SerialException if the connection is 145 | closed.""" 146 | if not self._isOpen: raise portNotOpenError 147 | # ensure we're working with bytes 148 | data = to_bytes(data) 149 | # calculate aprox time that would be used to send the data 150 | time_used_to_send = 10.0*len(data) / self._baudrate 151 | # when a write timeout is configured check if we would be successful 152 | # (not sending anything, not even the part that would have time) 153 | if self._writeTimeout is not None and time_used_to_send > self._writeTimeout: 154 | time.sleep(self._writeTimeout) # must wait so that unit test succeeds 155 | raise writeTimeoutError 156 | self.buffer_lock.acquire() 157 | try: 158 | self.loop_buffer += data 159 | finally: 160 | self.buffer_lock.release() 161 | return len(data) 162 | 163 | def flushInput(self): 164 | """Clear input buffer, discarding all that is in the buffer.""" 165 | if not self._isOpen: raise portNotOpenError 166 | if self.logger: 167 | self.logger.info('flushInput()') 168 | self.buffer_lock.acquire() 169 | try: 170 | del self.loop_buffer[:] 171 | finally: 172 | self.buffer_lock.release() 173 | 174 | def flushOutput(self): 175 | """Clear output buffer, aborting the current output and 176 | discarding all that is in the buffer.""" 177 | if not self._isOpen: raise portNotOpenError 178 | if self.logger: 179 | self.logger.info('flushOutput()') 180 | 181 | def sendBreak(self, duration=0.25): 182 | """Send break condition. Timed, returns to idle state after given 183 | duration.""" 184 | if not self._isOpen: raise portNotOpenError 185 | 186 | def setBreak(self, level=True): 187 | """Set break: Controls TXD. When active, to transmitting is 188 | possible.""" 189 | if not self._isOpen: raise portNotOpenError 190 | if self.logger: 191 | self.logger.info('setBreak(%r)' % (level,)) 192 | 193 | def setRTS(self, level=True): 194 | """Set terminal status line: Request To Send""" 195 | if not self._isOpen: raise portNotOpenError 196 | if self.logger: 197 | self.logger.info('setRTS(%r) -> state of CTS' % (level,)) 198 | self.cts = level 199 | 200 | def setDTR(self, level=True): 201 | """Set terminal status line: Data Terminal Ready""" 202 | if not self._isOpen: raise portNotOpenError 203 | if self.logger: 204 | self.logger.info('setDTR(%r) -> state of DSR' % (level,)) 205 | self.dsr = level 206 | 207 | def getCTS(self): 208 | """Read terminal status line: Clear To Send""" 209 | if not self._isOpen: raise portNotOpenError 210 | if self.logger: 211 | self.logger.info('getCTS() -> state of RTS (%r)' % (self.cts,)) 212 | return self.cts 213 | 214 | def getDSR(self): 215 | """Read terminal status line: Data Set Ready""" 216 | if not self._isOpen: raise portNotOpenError 217 | if self.logger: 218 | self.logger.info('getDSR() -> state of DTR (%r)' % (self.dsr,)) 219 | return self.dsr 220 | 221 | def getRI(self): 222 | """Read terminal status line: Ring Indicator""" 223 | if not self._isOpen: raise portNotOpenError 224 | if self.logger: 225 | self.logger.info('returning dummy for getRI()') 226 | return False 227 | 228 | def getCD(self): 229 | """Read terminal status line: Carrier Detect""" 230 | if not self._isOpen: raise portNotOpenError 231 | if self.logger: 232 | self.logger.info('returning dummy for getCD()') 233 | return True 234 | 235 | # - - - platform specific - - - 236 | # None so far 237 | 238 | 239 | # assemble Serial class with the platform specific implementation and the base 240 | # for file-like behavior. for Python 2.6 and newer, that provide the new I/O 241 | # library, derive from io.RawIOBase 242 | try: 243 | import io 244 | except ImportError: 245 | # classic version with our own file-like emulation 246 | class Serial(LoopbackSerial, FileLike): 247 | pass 248 | else: 249 | # io library present 250 | class Serial(LoopbackSerial, io.RawIOBase): 251 | pass 252 | 253 | 254 | # simple client test 255 | if __name__ == '__main__': 256 | import sys 257 | s = Serial('loop://') 258 | sys.stdout.write('%s\n' % s) 259 | 260 | sys.stdout.write("write...\n") 261 | s.write("hello\n") 262 | s.flush() 263 | sys.stdout.write("read: %s\n" % s.read(5)) 264 | 265 | s.close() 266 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/urlhandler/protocol_rfc2217.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # 3 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 4 | # see ../__init__.py 5 | # 6 | # This is a thin wrapper to load the rfc2271 implementation. 7 | # 8 | # (C) 2011 Chris Liechti 9 | # this is distributed under a free software license, see license.txt 10 | 11 | from serial.rfc2217 import Serial 12 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/urlhandler/protocol_socket.py: -------------------------------------------------------------------------------- 1 | #! python 2 | # 3 | # Python Serial Port Extension for Win32, Linux, BSD, Jython 4 | # see __init__.py 5 | # 6 | # This module implements a simple socket based client. 7 | # It does not support changing any port parameters and will silently ignore any 8 | # requests to do so. 9 | # 10 | # The purpose of this module is that applications using pySerial can connect to 11 | # TCP/IP to serial port converters that do not support RFC 2217. 12 | # 13 | # (C) 2001-2011 Chris Liechti 14 | # this is distributed under a free software license, see license.txt 15 | # 16 | # URL format: socket://:[/option[/option...]] 17 | # options: 18 | # - "debug" print diagnostic messages 19 | 20 | from serial.serialutil import * 21 | import time 22 | import socket 23 | import logging 24 | 25 | # map log level names to constants. used in fromURL() 26 | LOGGER_LEVELS = { 27 | 'debug': logging.DEBUG, 28 | 'info': logging.INFO, 29 | 'warning': logging.WARNING, 30 | 'error': logging.ERROR, 31 | } 32 | 33 | POLL_TIMEOUT = 2 34 | 35 | class SocketSerial(SerialBase): 36 | """Serial port implementation for plain sockets.""" 37 | 38 | BAUDRATES = (50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 39 | 9600, 19200, 38400, 57600, 115200) 40 | 41 | def open(self): 42 | """Open port with current settings. This may throw a SerialException 43 | if the port cannot be opened.""" 44 | self.logger = None 45 | if self._port is None: 46 | raise SerialException("Port must be configured before it can be used.") 47 | if self._isOpen: 48 | raise SerialException("Port is already open.") 49 | try: 50 | # XXX in future replace with create_connection (py >=2.6) 51 | self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 52 | self._socket.connect(self.fromURL(self.portstr)) 53 | except Exception, msg: 54 | self._socket = None 55 | raise SerialException("Could not open port %s: %s" % (self.portstr, msg)) 56 | 57 | self._socket.settimeout(POLL_TIMEOUT) # used for write timeout support :/ 58 | 59 | # not that there anything to configure... 60 | self._reconfigurePort() 61 | # all things set up get, now a clean start 62 | self._isOpen = True 63 | if not self._rtscts: 64 | self.setRTS(True) 65 | self.setDTR(True) 66 | self.flushInput() 67 | self.flushOutput() 68 | 69 | def _reconfigurePort(self): 70 | """Set communication parameters on opened port. for the socket:// 71 | protocol all settings are ignored!""" 72 | if self._socket is None: 73 | raise SerialException("Can only operate on open ports") 74 | if self.logger: 75 | self.logger.info('ignored port configuration change') 76 | 77 | def close(self): 78 | """Close port""" 79 | if self._isOpen: 80 | if self._socket: 81 | try: 82 | self._socket.shutdown(socket.SHUT_RDWR) 83 | self._socket.close() 84 | except: 85 | # ignore errors. 86 | pass 87 | self._socket = None 88 | self._isOpen = False 89 | # in case of quick reconnects, give the server some time 90 | time.sleep(0.3) 91 | 92 | def makeDeviceName(self, port): 93 | raise SerialException("there is no sensible way to turn numbers into URLs") 94 | 95 | def fromURL(self, url): 96 | """extract host and port from an URL string""" 97 | if url.lower().startswith("socket://"): url = url[9:] 98 | try: 99 | # is there a "path" (our options)? 100 | if '/' in url: 101 | # cut away options 102 | url, options = url.split('/', 1) 103 | # process options now, directly altering self 104 | for option in options.split('/'): 105 | if '=' in option: 106 | option, value = option.split('=', 1) 107 | else: 108 | value = None 109 | if option == 'logging': 110 | logging.basicConfig() # XXX is that good to call it here? 111 | self.logger = logging.getLogger('pySerial.socket') 112 | self.logger.setLevel(LOGGER_LEVELS[value]) 113 | self.logger.debug('enabled logging') 114 | else: 115 | raise ValueError('unknown option: %r' % (option,)) 116 | # get host and port 117 | host, port = url.split(':', 1) # may raise ValueError because of unpacking 118 | port = int(port) # and this if it's not a number 119 | if not 0 <= port < 65536: raise ValueError("port not in range 0...65535") 120 | except ValueError, e: 121 | raise SerialException('expected a string in the form "[rfc2217://]:[/option[/option...]]": %s' % e) 122 | return (host, port) 123 | 124 | # - - - - - - - - - - - - - - - - - - - - - - - - 125 | 126 | def inWaiting(self): 127 | """Return the number of characters currently in the input buffer.""" 128 | if not self._isOpen: raise portNotOpenError 129 | if self.logger: 130 | # set this one to debug as the function could be called often... 131 | self.logger.debug('WARNING: inWaiting returns dummy value') 132 | return 0 # hmmm, see comment in read() 133 | 134 | def read(self, size=1): 135 | """Read size bytes from the serial port. If a timeout is set it may 136 | return less characters as requested. With no timeout it will block 137 | until the requested number of bytes is read.""" 138 | if not self._isOpen: raise portNotOpenError 139 | data = bytearray() 140 | if self._timeout is not None: 141 | timeout = time.time() + self._timeout 142 | else: 143 | timeout = None 144 | while len(data) < size and (timeout is None or time.time() < timeout): 145 | try: 146 | # an implementation with internal buffer would be better 147 | # performing... 148 | t = time.time() 149 | block = self._socket.recv(size - len(data)) 150 | duration = time.time() - t 151 | if block: 152 | data.extend(block) 153 | else: 154 | # no data -> EOF (connection probably closed) 155 | break 156 | except socket.timeout: 157 | # just need to get out of recv from time to time to check if 158 | # still alive 159 | continue 160 | except socket.error, e: 161 | # connection fails -> terminate loop 162 | raise SerialException('connection failed (%s)' % e) 163 | return bytes(data) 164 | 165 | def write(self, data): 166 | """Output the given string over the serial port. Can block if the 167 | connection is blocked. May raise SerialException if the connection is 168 | closed.""" 169 | if not self._isOpen: raise portNotOpenError 170 | try: 171 | self._socket.sendall(to_bytes(data)) 172 | except socket.error, e: 173 | # XXX what exception if socket connection fails 174 | raise SerialException("socket connection failed: %s" % e) 175 | return len(data) 176 | 177 | def flushInput(self): 178 | """Clear input buffer, discarding all that is in the buffer.""" 179 | if not self._isOpen: raise portNotOpenError 180 | if self.logger: 181 | self.logger.info('ignored flushInput') 182 | 183 | def flushOutput(self): 184 | """Clear output buffer, aborting the current output and 185 | discarding all that is in the buffer.""" 186 | if not self._isOpen: raise portNotOpenError 187 | if self.logger: 188 | self.logger.info('ignored flushOutput') 189 | 190 | def sendBreak(self, duration=0.25): 191 | """Send break condition. Timed, returns to idle state after given 192 | duration.""" 193 | if not self._isOpen: raise portNotOpenError 194 | if self.logger: 195 | self.logger.info('ignored sendBreak(%r)' % (duration,)) 196 | 197 | def setBreak(self, level=True): 198 | """Set break: Controls TXD. When active, to transmitting is 199 | possible.""" 200 | if not self._isOpen: raise portNotOpenError 201 | if self.logger: 202 | self.logger.info('ignored setBreak(%r)' % (level,)) 203 | 204 | def setRTS(self, level=True): 205 | """Set terminal status line: Request To Send""" 206 | if not self._isOpen: raise portNotOpenError 207 | if self.logger: 208 | self.logger.info('ignored setRTS(%r)' % (level,)) 209 | 210 | def setDTR(self, level=True): 211 | """Set terminal status line: Data Terminal Ready""" 212 | if not self._isOpen: raise portNotOpenError 213 | if self.logger: 214 | self.logger.info('ignored setDTR(%r)' % (level,)) 215 | 216 | def getCTS(self): 217 | """Read terminal status line: Clear To Send""" 218 | if not self._isOpen: raise portNotOpenError 219 | if self.logger: 220 | self.logger.info('returning dummy for getCTS()') 221 | return True 222 | 223 | def getDSR(self): 224 | """Read terminal status line: Data Set Ready""" 225 | if not self._isOpen: raise portNotOpenError 226 | if self.logger: 227 | self.logger.info('returning dummy for getDSR()') 228 | return True 229 | 230 | def getRI(self): 231 | """Read terminal status line: Ring Indicator""" 232 | if not self._isOpen: raise portNotOpenError 233 | if self.logger: 234 | self.logger.info('returning dummy for getRI()') 235 | return False 236 | 237 | def getCD(self): 238 | """Read terminal status line: Carrier Detect""" 239 | if not self._isOpen: raise portNotOpenError 240 | if self.logger: 241 | self.logger.info('returning dummy for getCD()') 242 | return True 243 | 244 | # - - - platform specific - - - 245 | # None so far 246 | 247 | 248 | # assemble Serial class with the platform specific implementation and the base 249 | # for file-like behavior. for Python 2.6 and newer, that provide the new I/O 250 | # library, derive from io.RawIOBase 251 | try: 252 | import io 253 | except ImportError: 254 | # classic version with our own file-like emulation 255 | class Serial(SocketSerial, FileLike): 256 | pass 257 | else: 258 | # io library present 259 | class Serial(SocketSerial, io.RawIOBase): 260 | pass 261 | 262 | 263 | # simple client test 264 | if __name__ == '__main__': 265 | import sys 266 | s = Serial('socket://localhost:7000') 267 | sys.stdout.write('%s\n' % s) 268 | 269 | sys.stdout.write("write...\n") 270 | s.write("hello\n") 271 | s.flush() 272 | sys.stdout.write("read: %s\n" % s.read(5)) 273 | 274 | s.close() 275 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/serial/win32.py: -------------------------------------------------------------------------------- 1 | from ctypes import * 2 | from ctypes.wintypes import HANDLE 3 | from ctypes.wintypes import BOOL 4 | from ctypes.wintypes import LPCWSTR 5 | _stdcall_libraries = {} 6 | _stdcall_libraries['kernel32'] = WinDLL('kernel32') 7 | from ctypes.wintypes import DWORD 8 | from ctypes.wintypes import WORD 9 | from ctypes.wintypes import BYTE 10 | 11 | INVALID_HANDLE_VALUE = HANDLE(-1).value 12 | 13 | # some details of the windows API differ between 32 and 64 bit systems.. 14 | def is_64bit(): 15 | """Returns true when running on a 64 bit system""" 16 | return sizeof(c_ulong) != sizeof(c_void_p) 17 | 18 | # ULONG_PTR is a an ordinary number, not a pointer and contrary to the name it 19 | # is either 32 or 64 bits, depending on the type of windows... 20 | # so test if this a 32 bit windows... 21 | if is_64bit(): 22 | # assume 64 bits 23 | ULONG_PTR = c_int64 24 | else: 25 | # 32 bits 26 | ULONG_PTR = c_ulong 27 | 28 | 29 | class _SECURITY_ATTRIBUTES(Structure): 30 | pass 31 | LPSECURITY_ATTRIBUTES = POINTER(_SECURITY_ATTRIBUTES) 32 | 33 | 34 | try: 35 | CreateEventW = _stdcall_libraries['kernel32'].CreateEventW 36 | except AttributeError: 37 | # Fallback to non wide char version for old OS... 38 | from ctypes.wintypes import LPCSTR 39 | CreateEventA = _stdcall_libraries['kernel32'].CreateEventA 40 | CreateEventA.restype = HANDLE 41 | CreateEventA.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR] 42 | CreateEvent=CreateEventA 43 | 44 | CreateFileA = _stdcall_libraries['kernel32'].CreateFileA 45 | CreateFileA.restype = HANDLE 46 | CreateFileA.argtypes = [LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE] 47 | CreateFile = CreateFileA 48 | else: 49 | CreateEventW.restype = HANDLE 50 | CreateEventW.argtypes = [LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR] 51 | CreateEvent = CreateEventW # alias 52 | 53 | CreateFileW = _stdcall_libraries['kernel32'].CreateFileW 54 | CreateFileW.restype = HANDLE 55 | CreateFileW.argtypes = [LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE] 56 | CreateFile = CreateFileW # alias 57 | 58 | class _OVERLAPPED(Structure): 59 | pass 60 | OVERLAPPED = _OVERLAPPED 61 | 62 | class _COMSTAT(Structure): 63 | pass 64 | COMSTAT = _COMSTAT 65 | 66 | class _DCB(Structure): 67 | pass 68 | DCB = _DCB 69 | 70 | class _COMMTIMEOUTS(Structure): 71 | pass 72 | COMMTIMEOUTS = _COMMTIMEOUTS 73 | 74 | GetLastError = _stdcall_libraries['kernel32'].GetLastError 75 | GetLastError.restype = DWORD 76 | GetLastError.argtypes = [] 77 | 78 | LPOVERLAPPED = POINTER(_OVERLAPPED) 79 | LPDWORD = POINTER(DWORD) 80 | 81 | GetOverlappedResult = _stdcall_libraries['kernel32'].GetOverlappedResult 82 | GetOverlappedResult.restype = BOOL 83 | GetOverlappedResult.argtypes = [HANDLE, LPOVERLAPPED, LPDWORD, BOOL] 84 | 85 | ResetEvent = _stdcall_libraries['kernel32'].ResetEvent 86 | ResetEvent.restype = BOOL 87 | ResetEvent.argtypes = [HANDLE] 88 | 89 | LPCVOID = c_void_p 90 | 91 | WriteFile = _stdcall_libraries['kernel32'].WriteFile 92 | WriteFile.restype = BOOL 93 | WriteFile.argtypes = [HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED] 94 | 95 | LPVOID = c_void_p 96 | 97 | ReadFile = _stdcall_libraries['kernel32'].ReadFile 98 | ReadFile.restype = BOOL 99 | ReadFile.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED] 100 | 101 | CloseHandle = _stdcall_libraries['kernel32'].CloseHandle 102 | CloseHandle.restype = BOOL 103 | CloseHandle.argtypes = [HANDLE] 104 | 105 | ClearCommBreak = _stdcall_libraries['kernel32'].ClearCommBreak 106 | ClearCommBreak.restype = BOOL 107 | ClearCommBreak.argtypes = [HANDLE] 108 | 109 | LPCOMSTAT = POINTER(_COMSTAT) 110 | 111 | ClearCommError = _stdcall_libraries['kernel32'].ClearCommError 112 | ClearCommError.restype = BOOL 113 | ClearCommError.argtypes = [HANDLE, LPDWORD, LPCOMSTAT] 114 | 115 | SetupComm = _stdcall_libraries['kernel32'].SetupComm 116 | SetupComm.restype = BOOL 117 | SetupComm.argtypes = [HANDLE, DWORD, DWORD] 118 | 119 | EscapeCommFunction = _stdcall_libraries['kernel32'].EscapeCommFunction 120 | EscapeCommFunction.restype = BOOL 121 | EscapeCommFunction.argtypes = [HANDLE, DWORD] 122 | 123 | GetCommModemStatus = _stdcall_libraries['kernel32'].GetCommModemStatus 124 | GetCommModemStatus.restype = BOOL 125 | GetCommModemStatus.argtypes = [HANDLE, LPDWORD] 126 | 127 | LPDCB = POINTER(_DCB) 128 | 129 | GetCommState = _stdcall_libraries['kernel32'].GetCommState 130 | GetCommState.restype = BOOL 131 | GetCommState.argtypes = [HANDLE, LPDCB] 132 | 133 | LPCOMMTIMEOUTS = POINTER(_COMMTIMEOUTS) 134 | 135 | GetCommTimeouts = _stdcall_libraries['kernel32'].GetCommTimeouts 136 | GetCommTimeouts.restype = BOOL 137 | GetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS] 138 | 139 | PurgeComm = _stdcall_libraries['kernel32'].PurgeComm 140 | PurgeComm.restype = BOOL 141 | PurgeComm.argtypes = [HANDLE, DWORD] 142 | 143 | SetCommBreak = _stdcall_libraries['kernel32'].SetCommBreak 144 | SetCommBreak.restype = BOOL 145 | SetCommBreak.argtypes = [HANDLE] 146 | 147 | SetCommMask = _stdcall_libraries['kernel32'].SetCommMask 148 | SetCommMask.restype = BOOL 149 | SetCommMask.argtypes = [HANDLE, DWORD] 150 | 151 | SetCommState = _stdcall_libraries['kernel32'].SetCommState 152 | SetCommState.restype = BOOL 153 | SetCommState.argtypes = [HANDLE, LPDCB] 154 | 155 | SetCommTimeouts = _stdcall_libraries['kernel32'].SetCommTimeouts 156 | SetCommTimeouts.restype = BOOL 157 | SetCommTimeouts.argtypes = [HANDLE, LPCOMMTIMEOUTS] 158 | 159 | WaitForSingleObject = _stdcall_libraries['kernel32'].WaitForSingleObject 160 | WaitForSingleObject.restype = DWORD 161 | WaitForSingleObject.argtypes = [HANDLE, DWORD] 162 | 163 | ONESTOPBIT = 0 # Variable c_int 164 | TWOSTOPBITS = 2 # Variable c_int 165 | ONE5STOPBITS = 1 166 | 167 | NOPARITY = 0 # Variable c_int 168 | ODDPARITY = 1 # Variable c_int 169 | EVENPARITY = 2 # Variable c_int 170 | MARKPARITY = 3 171 | SPACEPARITY = 4 172 | 173 | RTS_CONTROL_HANDSHAKE = 2 # Variable c_int 174 | RTS_CONTROL_DISABLE = 0 # Variable c_int 175 | RTS_CONTROL_ENABLE = 1 # Variable c_int 176 | RTS_CONTROL_TOGGLE = 3 # Variable c_int 177 | SETRTS = 3 178 | CLRRTS = 4 179 | 180 | DTR_CONTROL_HANDSHAKE = 2 # Variable c_int 181 | DTR_CONTROL_DISABLE = 0 # Variable c_int 182 | DTR_CONTROL_ENABLE = 1 # Variable c_int 183 | SETDTR = 5 184 | CLRDTR = 6 185 | 186 | MS_DSR_ON = 32 # Variable c_ulong 187 | EV_RING = 256 # Variable c_int 188 | EV_PERR = 512 # Variable c_int 189 | EV_ERR = 128 # Variable c_int 190 | SETXOFF = 1 # Variable c_int 191 | EV_RXCHAR = 1 # Variable c_int 192 | GENERIC_WRITE = 1073741824 # Variable c_long 193 | PURGE_TXCLEAR = 4 # Variable c_int 194 | FILE_FLAG_OVERLAPPED = 1073741824 # Variable c_int 195 | EV_DSR = 16 # Variable c_int 196 | MAXDWORD = 4294967295L # Variable c_uint 197 | EV_RLSD = 32 # Variable c_int 198 | ERROR_IO_PENDING = 997 # Variable c_long 199 | MS_CTS_ON = 16 # Variable c_ulong 200 | EV_EVENT1 = 2048 # Variable c_int 201 | EV_RX80FULL = 1024 # Variable c_int 202 | PURGE_RXABORT = 2 # Variable c_int 203 | FILE_ATTRIBUTE_NORMAL = 128 # Variable c_int 204 | PURGE_TXABORT = 1 # Variable c_int 205 | SETXON = 2 # Variable c_int 206 | OPEN_EXISTING = 3 # Variable c_int 207 | MS_RING_ON = 64 # Variable c_ulong 208 | EV_TXEMPTY = 4 # Variable c_int 209 | EV_RXFLAG = 2 # Variable c_int 210 | MS_RLSD_ON = 128 # Variable c_ulong 211 | GENERIC_READ = 2147483648L # Variable c_ulong 212 | EV_EVENT2 = 4096 # Variable c_int 213 | EV_CTS = 8 # Variable c_int 214 | EV_BREAK = 64 # Variable c_int 215 | PURGE_RXCLEAR = 8 # Variable c_int 216 | INFINITE = 0xFFFFFFFFL 217 | 218 | 219 | class N11_OVERLAPPED4DOLLAR_48E(Union): 220 | pass 221 | class N11_OVERLAPPED4DOLLAR_484DOLLAR_49E(Structure): 222 | pass 223 | N11_OVERLAPPED4DOLLAR_484DOLLAR_49E._fields_ = [ 224 | ('Offset', DWORD), 225 | ('OffsetHigh', DWORD), 226 | ] 227 | 228 | PVOID = c_void_p 229 | 230 | N11_OVERLAPPED4DOLLAR_48E._anonymous_ = ['_0'] 231 | N11_OVERLAPPED4DOLLAR_48E._fields_ = [ 232 | ('_0', N11_OVERLAPPED4DOLLAR_484DOLLAR_49E), 233 | ('Pointer', PVOID), 234 | ] 235 | _OVERLAPPED._anonymous_ = ['_0'] 236 | _OVERLAPPED._fields_ = [ 237 | ('Internal', ULONG_PTR), 238 | ('InternalHigh', ULONG_PTR), 239 | ('_0', N11_OVERLAPPED4DOLLAR_48E), 240 | ('hEvent', HANDLE), 241 | ] 242 | _SECURITY_ATTRIBUTES._fields_ = [ 243 | ('nLength', DWORD), 244 | ('lpSecurityDescriptor', LPVOID), 245 | ('bInheritHandle', BOOL), 246 | ] 247 | _COMSTAT._fields_ = [ 248 | ('fCtsHold', DWORD, 1), 249 | ('fDsrHold', DWORD, 1), 250 | ('fRlsdHold', DWORD, 1), 251 | ('fXoffHold', DWORD, 1), 252 | ('fXoffSent', DWORD, 1), 253 | ('fEof', DWORD, 1), 254 | ('fTxim', DWORD, 1), 255 | ('fReserved', DWORD, 25), 256 | ('cbInQue', DWORD), 257 | ('cbOutQue', DWORD), 258 | ] 259 | _DCB._fields_ = [ 260 | ('DCBlength', DWORD), 261 | ('BaudRate', DWORD), 262 | ('fBinary', DWORD, 1), 263 | ('fParity', DWORD, 1), 264 | ('fOutxCtsFlow', DWORD, 1), 265 | ('fOutxDsrFlow', DWORD, 1), 266 | ('fDtrControl', DWORD, 2), 267 | ('fDsrSensitivity', DWORD, 1), 268 | ('fTXContinueOnXoff', DWORD, 1), 269 | ('fOutX', DWORD, 1), 270 | ('fInX', DWORD, 1), 271 | ('fErrorChar', DWORD, 1), 272 | ('fNull', DWORD, 1), 273 | ('fRtsControl', DWORD, 2), 274 | ('fAbortOnError', DWORD, 1), 275 | ('fDummy2', DWORD, 17), 276 | ('wReserved', WORD), 277 | ('XonLim', WORD), 278 | ('XoffLim', WORD), 279 | ('ByteSize', BYTE), 280 | ('Parity', BYTE), 281 | ('StopBits', BYTE), 282 | ('XonChar', c_char), 283 | ('XoffChar', c_char), 284 | ('ErrorChar', c_char), 285 | ('EofChar', c_char), 286 | ('EvtChar', c_char), 287 | ('wReserved1', WORD), 288 | ] 289 | _COMMTIMEOUTS._fields_ = [ 290 | ('ReadIntervalTimeout', DWORD), 291 | ('ReadTotalTimeoutMultiplier', DWORD), 292 | ('ReadTotalTimeoutConstant', DWORD), 293 | ('WriteTotalTimeoutMultiplier', DWORD), 294 | ('WriteTotalTimeoutConstant', DWORD), 295 | ] 296 | __all__ = ['GetLastError', 'MS_CTS_ON', 'FILE_ATTRIBUTE_NORMAL', 297 | 'DTR_CONTROL_ENABLE', '_COMSTAT', 'MS_RLSD_ON', 298 | 'GetOverlappedResult', 'SETXON', 'PURGE_TXABORT', 299 | 'PurgeComm', 'N11_OVERLAPPED4DOLLAR_48E', 'EV_RING', 300 | 'ONESTOPBIT', 'SETXOFF', 'PURGE_RXABORT', 'GetCommState', 301 | 'RTS_CONTROL_ENABLE', '_DCB', 'CreateEvent', 302 | '_COMMTIMEOUTS', '_SECURITY_ATTRIBUTES', 'EV_DSR', 303 | 'EV_PERR', 'EV_RXFLAG', 'OPEN_EXISTING', 'DCB', 304 | 'FILE_FLAG_OVERLAPPED', 'EV_CTS', 'SetupComm', 305 | 'LPOVERLAPPED', 'EV_TXEMPTY', 'ClearCommBreak', 306 | 'LPSECURITY_ATTRIBUTES', 'SetCommBreak', 'SetCommTimeouts', 307 | 'COMMTIMEOUTS', 'ODDPARITY', 'EV_RLSD', 308 | 'GetCommModemStatus', 'EV_EVENT2', 'PURGE_TXCLEAR', 309 | 'EV_BREAK', 'EVENPARITY', 'LPCVOID', 'COMSTAT', 'ReadFile', 310 | 'PVOID', '_OVERLAPPED', 'WriteFile', 'GetCommTimeouts', 311 | 'ResetEvent', 'EV_RXCHAR', 'LPCOMSTAT', 'ClearCommError', 312 | 'ERROR_IO_PENDING', 'EscapeCommFunction', 'GENERIC_READ', 313 | 'RTS_CONTROL_HANDSHAKE', 'OVERLAPPED', 314 | 'DTR_CONTROL_HANDSHAKE', 'PURGE_RXCLEAR', 'GENERIC_WRITE', 315 | 'LPDCB', 'CreateEventW', 'SetCommMask', 'EV_EVENT1', 316 | 'SetCommState', 'LPVOID', 'CreateFileW', 'LPDWORD', 317 | 'EV_RX80FULL', 'TWOSTOPBITS', 'LPCOMMTIMEOUTS', 'MAXDWORD', 318 | 'MS_DSR_ON', 'MS_RING_ON', 319 | 'N11_OVERLAPPED4DOLLAR_484DOLLAR_49E', 'EV_ERR', 320 | 'ULONG_PTR', 'CreateFile', 'NOPARITY', 'CloseHandle'] 321 | -------------------------------------------------------------------------------- /Snap!Files/Snap!Mobile/arduino/xlate.cfg: -------------------------------------------------------------------------------- 1 | # @author: Alan Yorinks 2 | # Copyright (c) 2013 Alan Yorinks All right reserved. 3 | # 4 | # @co-author: Sjoerd Dirk Meijer, fromScratchEd.nl (language support) 5 | # @co-author: Professor José Manuel Ruiz (Spanish translation) 6 | # 7 | # This program is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | #version 2.1 of the License, or (at your option) any later version. 11 | # 12 | # This library is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | # Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public 18 | # License along with this library; if not, write to the Free Software 19 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | [translation_lists] 22 | ln_languages = English,Dutch (NL),Spanish 23 | ln_ENABLE = Enable,aan,Activar 24 | ln_DISABLE =Disable,uit,Desactivar 25 | ln_INPUT = Input,ingang,Entrada 26 | ln_OUTPUT = Output,uitgang,Salida 27 | ln_PWM = PWM,PWM,PWM 28 | ln_SERVO = Servo,servo,Servo 29 | ln_TONE = Tone,toon,Tono 30 | ln_SONAR = SONAR,afstand,Sonar 31 | ln_OFF = Off,uitgeschakeld,No 32 | ln_ON = On,ingeschakeld,Si 33 | -------------------------------------------------------------------------------- /documentation/Español/s2a_fm_Espanish_tutorial.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/Español/s2a_fm_Espanish_tutorial.pdf -------------------------------------------------------------------------------- /documentation/LED_EXAMPLE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/LED_EXAMPLE.png -------------------------------------------------------------------------------- /documentation/pot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/pot1.png -------------------------------------------------------------------------------- /documentation/s2a_fm_reference - 完成稿.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/s2a_fm_reference - 完成稿.pdf -------------------------------------------------------------------------------- /documentation/s2a_fm_reference.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/s2a_fm_reference.pdf -------------------------------------------------------------------------------- /documentation/s2a_fm_參考文件.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/s2a_fm_參考文件.pdf -------------------------------------------------------------------------------- /documentation/scratch_blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/scratch_blocks.png -------------------------------------------------------------------------------- /documentation/scratch_langs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/scratch_langs.png -------------------------------------------------------------------------------- /documentation/snap_blocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MrYsLab/s2a_fm/4a00749da24dae9152698c872a4f30d9a25cc214/documentation/snap_blocks.png -------------------------------------------------------------------------------- /extra_goodies/linux/s2a_fm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Modify this file for your serial port designator. 4 | # Move this file to the directory that contains s2a_fm.py 5 | # and execute it by typing "./s2a_fm.sh" 6 | # Make sure that this file is executable as well as s2a_fm.py 7 | 8 | python s2a_fm.py /dev/ttyACM0 9 | 10 | -------------------------------------------------------------------------------- /extra_goodies/windows/s2a_fm.bat: -------------------------------------------------------------------------------- 1 | REM Modify this file for your serial port designator and for the location of 2 | REM python. 3 | REM Move this file to the directory that contains s2a_fm.py 4 | REM and execute it by opening the file explorer and double clicking. 5 | REM You can also create a desktop shortcut if you like. 6 | REM Right click on this file in the Windows File Explorer and select shortcut to create the shortcut. 7 | REM Make sure that this file is executable as well as s2a_fm.py 8 | 9 | c:\python27\python s2a_fm.py com3 10 | 11 | -------------------------------------------------------------------------------- /s2a_fm.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # -*- coding: utf-8 -*- 4 | 5 | """ 6 | Created on Wed Nov 25 13:17:15 2013 7 | 8 | @author: Alan Yorinks 9 | Copyright (c) 2013-14 Alan Yorinks All right reserved. 10 | 11 | This program is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU Lesser General Public 13 | License as published by the Free Software Foundation; either 14 | version 2.1 of the License, or (at your option) any later version. 15 | 16 | This library is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | Lesser General Public License for more details. 20 | 21 | You should have received a copy of the GNU Lesser General Public 22 | License along with this library; if not, write to the Free Software 23 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 | 25 | """ 26 | import os 27 | import sys 28 | import logging 29 | from PyMata.pymata import PyMata 30 | import scratch_http_server 31 | from scratch_command_handlers import ScratchCommandHandlers 32 | import time 33 | 34 | 35 | #noinspection PyBroadException 36 | def s2a_fm(): 37 | 38 | """ 39 | This is the "main" function of the program. 40 | It will instantiate PyMata for communication with an Arduino micro-controller 41 | and the command handlers class. 42 | It will the start the HTTP server to communicate with Scratch 2.0 43 | @return : This is the main loop and should never return 44 | """ 45 | # total number of pins on arduino board 46 | total_pins_discovered = 0 47 | # number of pins that are analog 48 | number_of_analog_pins_discovered = 0 49 | 50 | # make sure we have a log directory and if not, create it. 51 | if not os.path.exists('log'): 52 | os.makedirs('log') 53 | 54 | # turn on logging 55 | logging.basicConfig(filename='./log/s2a_fm_debugging.log', filemode='w', level=logging.DEBUG) 56 | logging.info('s2a_fm version 1.5 Copyright(C) 2013-14 Alan Yorinks All Rights Reserved ') 57 | print 's2a_fm version 1.5 Copyright(C) 2013-14 Alan Yorinks All Rights Reserved ' 58 | 59 | # get the com_port from the command line or default if none given 60 | # if user specified the com port on the command line, use that when invoking PyMata, 61 | # else use '/dev/ttyACM0' 62 | if len(sys.argv) == 2: 63 | com_port = str(sys.argv[1]) 64 | else: 65 | com_port = '/dev/ttyACM0' 66 | logging.info('com port = %s' % com_port) 67 | 68 | try: 69 | # instantiate PyMata 70 | firmata = PyMata(com_port) # pragma: no cover 71 | except Exception: 72 | print 'Could not instantiate PyMata - is your Arduino plugged in?' 73 | logging.exception('Could not instantiate PyMata - is your Arduino plugged in?') 74 | logging.debug("Exiting s2a_fm") 75 | return 76 | 77 | # determine the total number of pins and the number of analog pins for the Arduino 78 | # get the arduino analog pin map 79 | # it will contain an entry for all the pins with non-analog set to firmata.IGNORE 80 | firmata.analog_mapping_query() 81 | 82 | capability_map = firmata.get_analog_mapping_request_results() 83 | 84 | firmata.capability_query() 85 | print "Please wait for Total Arduino Pin Discovery to complete. This can take up to 30 additional seconds." 86 | 87 | # count the pins 88 | for pin in capability_map: 89 | total_pins_discovered += 1 90 | # non analog pins will be marked as IGNORE 91 | if pin != firmata.IGNORE: 92 | number_of_analog_pins_discovered += 1 93 | 94 | # log the number of pins found 95 | logging.info('%d Total Pins and %d Analog Pins Found' % (total_pins_discovered, number_of_analog_pins_discovered)) 96 | 97 | # instantiate the command handler 98 | scratch_command_handler = ScratchCommandHandlers(firmata, com_port, total_pins_discovered, 99 | number_of_analog_pins_discovered) 100 | 101 | # wait for a maximum of 30 seconds to retrieve the Arduino capability query 102 | start_time = time.time() 103 | 104 | pin_capability = firmata.get_capability_query_results() 105 | while not pin_capability: 106 | if time.time() - start_time > 30: 107 | print '' 108 | print "Could not determine pin capability - exiting." 109 | firmata.close() 110 | # keep sending out a capability query until there is a response 111 | pin_capability = firmata.get_capability_query_results() 112 | time.sleep(.1) 113 | 114 | # we've got the capability, now build a dictionary with pin as the key and a list of all the capabilities 115 | # for the pin as the key's value 116 | pin_list = [] 117 | total_pins_discovered = 0 118 | for entry in pin_capability: 119 | # bump up pin counter each time IGNORE is found 120 | if entry == firmata.IGNORE: 121 | scratch_command_handler.pin_map[total_pins_discovered] = pin_list 122 | total_pins_discovered += 1 123 | pin_list = [] 124 | else: 125 | pin_list.append(entry) 126 | 127 | print "Arduino Total Pin Discovery completed in %d seconds" % (int(time.time() - start_time)) 128 | 129 | try: 130 | # start the server passing it the handle to PyMata and the command handler. 131 | scratch_http_server.start_server(firmata, scratch_command_handler) 132 | 133 | except Exception: 134 | logging.debug('Exception in s2a_fm.py %s' % str(Exception)) 135 | firmata.close() 136 | return 137 | 138 | except KeyboardInterrupt: 139 | # give control back to the shell that started us 140 | logging.info('s2a_fm.py: keyboard interrupt exception') 141 | firmata.close() 142 | return 143 | 144 | if __name__ == "__main__": 145 | s2a_fm() -------------------------------------------------------------------------------- /scratch_http_server.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Mon Nov 25 14:45:49 2013 4 | 5 | @author: Alan Yorinks 6 | Copyright (c) 2013-14 Alan Yorinks All right reserved. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library; if not, write to the Free Software 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | """ 22 | 23 | import logging 24 | from BaseHTTPServer import BaseHTTPRequestHandler 25 | from BaseHTTPServer import HTTPServer 26 | from string import split 27 | 28 | 29 | class GetHandler(BaseHTTPRequestHandler): 30 | """ 31 | This class contains the HTTP server that Scratch2 communicates with 32 | Scratch sends HTTP GET requests and this class processes the requests. 33 | 34 | HTTP GET requests are accepted and the appropriate command handler is 35 | called to process the command. 36 | """ 37 | 38 | firmata = None 39 | 40 | # tcp server port - must match that in the .s2e descriptor file 41 | port = 50209 42 | 43 | # instance handle for the scratch command handler 44 | scratch_command_handler = None 45 | 46 | #indicator so that we can tell user Scratch is ready to go 47 | waiting_for_first_scratch_poll = True 48 | 49 | # this is a 'classmethod' because we need to set data before starting 50 | # the HTTP server. 51 | #noinspection PyMethodParameters 52 | @classmethod 53 | def set_items(self, firmata, scratch_command_handler): 54 | """ 55 | This method stores the input parameters for later use. 56 | It is a class method, because these values need to established 57 | prior to instantiating the class 58 | """ 59 | # instance variable for PyMata 60 | #noinspection PyAttributeOutsideInit 61 | self.firmata = firmata 62 | 63 | # instance variable for scratch command handler 64 | #noinspection PyAttributeOutsideInit 65 | self.command_handler = scratch_command_handler 66 | 67 | #noinspection PyPep8Naming 68 | def do_GET(self): 69 | """ 70 | Scratch2 only sends HTTP GET commands. This method processes them. 71 | It differentiates between a "normal" command request and a request 72 | to send policy information to keep Flash happy on Scratch. 73 | (This may change when Scratch is converted to HTML 5 74 | """ 75 | 76 | # skip over the / in the command 77 | cmd = self.path[1:] 78 | # create a list containing the command and all of its parameters 79 | cmd_list = split(cmd, '/') 80 | 81 | # get the command handler method for the command and call the handler 82 | # cmd_list[0] contains the command. look up the command method 83 | 84 | s = self.command_handler.do_command(cmd_list) 85 | 86 | # if pin was not enabled for reporter block, a "NoneType" can be returned by the command_handler 87 | if (s is None) or (len(s) == 0): 88 | 89 | err_statement = ("do_GET: Do you have all active pins enabled? " + str(cmd_list)) 90 | logging.info(err_statement) 91 | print err_statement 92 | return 93 | else: 94 | self.send_resp(s) 95 | 96 | # we can't use the standard send_response since we don't conform to its 97 | # standards, so we craft our own response handler here 98 | def send_resp(self, response): 99 | """ 100 | This method sends Scratch an HTTP response to an HTTP GET command. 101 | """ 102 | 103 | crlf = "\r\n" 104 | # http_response = str(response + crlf) 105 | http_response = "HTTP/1.1 200 OK" + crlf 106 | http_response += "Content-Type: text/html; charset=ISO-8859-1" + crlf 107 | http_response += "Content-Length" + str(len(response)) + crlf 108 | http_response += "Access-Control-Allow-Origin: *" + crlf 109 | http_response += crlf 110 | #add the response to the nonsense above 111 | if response != 'okay': 112 | http_response += str(response + crlf) 113 | # send it out the door to Scratch 114 | self.wfile.write(http_response) 115 | 116 | 117 | def start_server(firmata, command_handler): 118 | """ 119 | This function populates class variables with essential data and 120 | instantiates the HTTP Server 121 | """ 122 | 123 | GetHandler.set_items(firmata, command_handler) 124 | try: 125 | server = HTTPServer(('localhost', 50209), GetHandler) 126 | print 'Starting HTTP Server!' 127 | print 'Use to exit the extension\n' 128 | print 'Please start Scratch or Snap!' 129 | except Exception: 130 | logging.debug('Exception in scratch_http_server.py: HTTP Socket may already be in use - restart Scratch') 131 | print 'HTTP Socket may already be in use - restart Scratch' 132 | raise 133 | try: 134 | #start the server 135 | server.serve_forever() 136 | except KeyboardInterrupt: 137 | logging.info('scratch_http_server.py: keyboard interrupt exception') 138 | print "Goodbye !" 139 | raise KeyboardInterrupt 140 | except Exception: 141 | logging.debug('scratch_http_server.py: Exception %s' % str(Exception)) 142 | raise -------------------------------------------------------------------------------- /xlate.cfg: -------------------------------------------------------------------------------- 1 | # @author: Alan Yorinks 2 | # Copyright (c) 2013-2014 Alan Yorinks All right reserved. 3 | # 4 | # @co-author: Sjoerd Dirk Meijer, fromScratchEd.nl (language support) 5 | # @co-author: Professor José Manuel Ruiz (Spanish translation) 6 | # @co-author: Professor yufangjun (Chinese translation) 7 | # @co-author: Sebastien Canet (French translation) 8 | # @co-author: Aldo von Wangenheim, from www.computacaonaescola.ufsc.br (Portuguese translation) 9 | # @co-author: Aldo von Wangenheim, from www.computacaonaescola.ufsc.br (German translation) 10 | # @co-author: Dr. Eungil Kim (Korean Translation) 11 | # @co-author: Hsu Jen-Chieh (Chinese-TW translation) 12 | # @co-author: Gianfranco Zuliani (Italian translation) 13 | # @co-author: Alexandros Moskofidis (Greek translation) 14 | # @co-author: Antoine Choppin (Japanese translation) 15 | # 16 | # This program is free software; you can redistribute it and/or 17 | # modify it under the terms of the GNU Lesser General Public 18 | # License as published by the Free Software Foundation; either 19 | #version 2.1 of the License, or (at your option) any later version. 20 | # 21 | # This library is distributed in the hope that it will be useful, 22 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | # Lesser General Public License for more details. 25 | # 26 | # You should have received a copy of the GNU Lesser General Public License 27 | # along with this library; if not, write to the Free Software 28 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 29 | 30 | # NOTE: The Chinese and French translation strings are the values that are sent by the 31 | # Scratch program. Also, for French and Chinese, the translations in Snap! are written directly 32 | # into the blocks. 33 | 34 | [translation_lists] 35 | ln_languages = English,Dutch (NL),Spanish,��������(zh_cn),French(FR),Portuguese(PT),German(DE),Korean(KO), Chinese(zh_tw),Italian(IT),Greek(GR),Japanese(JA),Japanese2(JA2) 36 | ln_ENABLE = Enable,aan,Activar,%E5%85%81%E8%AE%B8,Activer,Ativar,Setze,%EC%82%AC%EC%9A%A9,%E5%95%9F%E7%94%A8,Attiva,%CE%95%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7,%E6%9C%89%E5%8A%B9,%E4%BD%BF%E3%81%86 37 | ln_DISABLE =Disable,uit,Desactivar,%E7%A6%81%E6%AD%A2,Desactiver,Desativar,Deaktiviere,%EB%AF%B8%EC%82%AC%EC%9A%A9,%E5%81%9C%E7%94%A8,Disattiva,%CE%91%CF%80%CE%B5%CE%BD%CE%B5%CF%81%CE%B3%CE%BF%CF%80%CE%BF%CE%AF%CE%B7%CF%83%CE%B7,%E7%84%A1%E5%8A%B9,%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84 38 | ln_INPUT = Input,ingang,Entrada,%E8%BE%93%E5%85%A5,entree,Entrada,Eingang,%EC%9E%85%EB%A0%A5,%E8%BC%B8%E5%85%A5,Ingresso,%CE%95%CE%AF%CF%83%CE%BF%CE%B4%CE%BF,%E5%85%A5%E5%8A%9B,%E5%85%A5%E5%8A%9B 39 | ln_OUTPUT = Output,uitgang,Salida,%E8%BE%93%E5%87%BA,sortie,Sa%C3%ADda,Ausgang,%EC%B6%9C%EB%A0%A5,%E8%BC%B8%E5%87%BA,Uscita,%CE%88%CE%BE%CE%BF%CE%B4%CE%BF,%E5%87%BA%E5%8A%9B,%E5%87%BA%E5%8A%9B 40 | ln_PWM = PWM,PWM,PWM,PWM,impulsion%20PWM,PWM,PWM,%EC%A0%84%EB%A5%98%EC%A1%B0%EC%A0%88,PWM,PWM,PWM,PWM%E6%B3%A2,PWM 41 | ln_SERVO = Servo,servo,Servo,%E8%88%B5%E6%9C%BA,rotation%20Servo-moteur.,Servo,Servo,%EC%84%9C%EB%B3%B4%EB%AA%A8%ED%84%B0,%E4%BC%BA%E6%9C%8D%E6%A9%9F,Servo,%CE%A3%CE%AD%CF%81%CE%B2%CE%BF,%E3%82%B5%E3%83%BC%E3%83%9C%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E5%9B%9E%E8%BB%A2,%E3%82%B5%E3%83%BC%E3%83%9C 42 | ln_TONE = Tone,toon,Tono,%E9%9F%B3%E8%B0%83,sortie%20Son.,Som,Ton,%EC%8B%A0%ED%98%B8%EC%9D%8C,%E9%9F%B3%E8%AA%BF,Tono,%CE%A4%CF%8C%CE%BD%CE%BF%CF%82,%E9%9F%B3%E5%A3%B0%E5%87%BA%E5%8A%9B,%E9%9F%B3 43 | ln_SONAR = SONAR,afstand,Sonar,%E8%B6%85%E5%A3%B0%E6%B3%A2,mesure%20Sonar.,Ultrassom,Ultraschall,%EC%9D%8C%ED%8C%8C%ED%83%90%EC%A7%80,%E8%B6%85%E9%9F%B3%E6%B3%A2,Sonar,%CE%A3%CF%8C%CE%BD%CE%B1%CF%81,%E8%B6%85%E9%9F%B3%E6%B3%A2%E3%81%AE%E8%B7%9D%E9%9B%A2%E6%B8%AC%E5%AE%9A,%E3%82%BD%E3%83%8A%E3%83%BC 44 | ln_OFF = Off,uitgeschakeld,No,%E5%85%B3,Arret,N%C3%A3o,Nein,%EB%81%84%EA%B8%B0,%E9%97%9C,No,%CE%9A%CE%BB%CE%B5%CE%AF%CF%83%CE%B9%CE%BC%CE%BF,%E6%AD%A2%E3%82%81%E3%82%8B,%E6%AD%A2%E3%82%81%E3%82%8B 45 | ln_ON = On,ingeschakeld,Si,%E5%BC%80,Marche,Sim,Ja,%EC%BC%9C%EA%B8%B0,%E9%96%8B,Si,%CE%86%CE%BD%CE%BF%CE%B9%CE%B3%CE%BC%CE%B1,%E5%8B%95%E3%81%8B%E3%81%99,%E5%8B%95%E3%81%8B%E3%81%99 46 | --------------------------------------------------------------------------------