├── 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 | [](https://gitter.im/MrYsLab/s2a_fm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5 |
6 |
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 | 
128 |
129 | Snap! s2a_fm Extension Blocks
130 | -----------------------------
131 | 
132 |
133 | Wiring Diagrams for Examples
134 | ----------------------------
135 |
136 | 
137 |
138 | 
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
1
data
mapmany1
data 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 |
--------------------------------------------------------------------------------