├── LISEZMOI.md
├── README.md
├── arduinoDcc1.3.brd
├── arduinoDcc1.3.sch
├── arduinoSource
└── dccduino
│ ├── DCC_Decoder.cpp
│ ├── DCC_Decoder.h
│ └── dccduino.ino
├── arduinov1.2.zip
├── arduinov1.3.zip
├── doc
├── README.md
├── arduinodcc.JPG
├── arduinodcc.xcf
├── arduinodccExplanation.JPG
├── arduinodccExplanation2.JPG
├── schemaEagle.png
└── schemaEagle2.png
├── docs
├── Makefile
├── arduinodcc.JPG
├── arduinodccExplanation.JPG
├── arduinodccExplanation2.JPG
├── basics.rst
├── conf.py
├── index.md
├── index.rst
├── make.bat
├── schemaEagle.png
└── schemaEagle2.png
└── gpl-2.0.txt
/LISEZMOI.md:
--------------------------------------------------------------------------------
1 | Un decodeur d'accessoire DCC versatile basé sur Arduino
2 | =======================================================
3 |
4 | 
5 |
6 | Quand j'ai commencé à construire mon réseau à l'échelle N, j'ai regardé pour piloter des lumières (SMD 0402, ou des led standards), mais j'avais soit de la difficulté à les programmer simplement (CV & co), ou je suis tombé sur des décodeurs à fabriquer soi-meme que je n'ai pas réussi à faire fonctionner. Du coup j'ai décidé de construire le mien en partant d'un Arduino nano, qui soit facile à reprogrammer.
7 |
8 | Ce décodeur est assez simple. On peut
9 | * lui assigner une adresse DCC (via un bouton d'apprentissage)
10 | * le connecter à des lampes LED ou utiliser comme relai
11 | * pour les lampes LED, on peut choisir différents modes, via un bouton poussoir. On peut avoir une lumière constante, une lumière qui grésille, ou avoir les 3 sorties en mode chenillard pour représenter par exemple des feux de travaux.
12 |
13 | Ce décodeur a été concu pour etre alimenté par du 16V alternatif, mais on peut aussi l'alimenter via le DCC directement (15v ou 18v) ou via un un signal 16V continu
14 |
15 |
16 | L'utiliser
17 | ==========
18 |
19 | 
20 |
21 | L'alimenter
22 | -----------
23 | Ce decodeur a été concu pour etre alimenté par une source 16V alternatif. Il est possible de l'alimenter directement par le signal DCC, mais le circuit n'est pas le le plus efficace en terme de consommation électrique (on alimente un Arduino, des lampes, et éventuellement un relai. Ca fait beaucoup), et dans la plupart des cas, on voudra surement éviter de bouffer tout le courant du signal DCC au détriment des locomotives...
24 |
25 |
26 | C'est pour cela qu'il y a 2 jeux de cables:
27 | * un pour l'alimentation 16V alternatif
28 | * un pour le signal DCC
29 |
30 | Assigner une adresse DCC
31 | ------------------------
32 |
33 | Pour assigner une adresse DCC, il suffit de mettre le bouton d'apprentissage à l'opposé de l'arduino.
34 | Dans cette position, chaque fois que le décodeur voit une commande passer, il va stocker l'adresse utilisée comme étant son adresse (et va le confirmer en faisant clignoter sa led de status).
35 | Donc pour assiger une adresse dcc il suffit de :
36 | * pousser le bouton d'apprentissage à l'opposé de l'arduino
37 | * envoyé une commande DCC avec l'adresse souhaitée
38 | * la led de statut va clignoter pour signifier qu'elle a bien vu et appris l'adresse
39 | * remettre le bouton d'apprentissage vers l'arduino
40 |
41 |
42 | Connecter des LED
43 | -----------------
44 |
45 | Dans le bas de la carte, il y a 3 slots pour leds. Le + est a gauche. Des resistances sont déjà prévues pour éviter de claquer les leds. Normalement vous connecter une led par slot seulement (du au fait que chaque led a une tension nominale qui varie d'une led a une autre)
46 |
47 | Ensuite, si vous utilisez le bouton poussoir, vous allez boucler entre 3 modes:
48 | * lumière constante (que ce soit alumé ou eteint)
49 | * grésillement/vacillement aléatoire (pour faire vieux néon d'entrepot)
50 | * feux de travaux sous forme de chenillard à 3 canaux (la première lampe va s'allumer, puis ca va etre la 2eme, puis la 3eme, puis de nouveau la 1ere)
51 |
52 | Il y a juste à appuyer sur le bouton poussoir pour boucler entre les 3 modes. La led de statut va vous dire dans quel mode vous etes.
53 |
54 |
55 | Connecter au relay
56 | ------------------
57 |
58 | Juste a coté des slots pour LED, il y a un slot avec 3 IO. Il s'agit du relai. Les 3 IO sont: sortie A, entree, sortie B
59 | Donc l'IO du milieu etre votre entrée (quelque soit le type "d'entrée" que vous avez), et le relai va connecter cette entrée soit sur l'IO de gauche, soit l'IO de droite.
60 |
61 | Connecter les autres IO
62 | =======================
63 |
64 | 
65 |
66 | En plus des led et du relai il y a des IO generiques, qui mettent à disposition:
67 | * le 5v et la masse de l'arduino
68 | * les sorties analogiques 6 et 7 de l'arduino
69 | * etles sorties numériques 6 et 7 de l'arduino
70 |
71 | Vous pouvez les utiliser à votre avantage, mais il faudra faire un peu de programmation: je n'ai rien codé pour sortir un quelconque signal par ces sorties, dans le programme fourni par défaut
72 |
73 | Assember
74 | ========
75 |
76 | Si vous voulez un décodeur tout fait, vous pouvez me contacter et je peux en fournir un: nicolas.zin@gmail.com
77 |
78 | Dans le cas contraire, vous pouvez l'assemblez vous meme. vous aurez juste besoin du circuit imprimé, et bien entendu des composants.
79 | Les fichiers gerber pour le cicruit imprimé sont disponible ici: [arduinov1.3.zip](arduinov1.3.zip) (pour le code source eagle, voir plus bas)
80 |
81 | Pour l'assemblage complet, voici le "Bill Of Material":
82 |
83 |
84 | Composant |nombre |ref
85 | ------------------------|---------|------------------------------------
86 | arduino nano |1 |aliexpress
87 | bridge rectifier |1 |mouser 625-B40C800G-E4
88 | capa 330uF |1 |mouser 667-EEU-FM1C331
89 | capa 10uF |1 |mouser 581-TAP106K025SCS
90 | DC-DC converter (9VDC) |1 |mouser 490-V7809-1000 (ou moins cher: voltage regulator mouser 511-L7809CV mais il est recommandé d'acheter un radiateur)
91 | R 50 ohm |1 |mouser 71-CPF150R000FEE14
92 | relay |1 |sparkfun COM-00100
93 | diode 4004 |1 |mouser 512-1N4004
94 | transistor 2n2222 |1 |mouser 610-2N2222
95 | R 10k ohm |5 |mouser 71-CCF50-10K
96 | R 1k ohm |1 |mouser 603-CFR-12JR-521K
97 | diode 4148 |1 |mouser 512-1N4148
98 | toggle button |1 |sparkfun COM-00102 (maybe mouser 633-SS12SDP2)
99 | push button |1 |SPARKUN COM-00097 (ou mouser 693-1301.9308)
100 | led |1 |mouser 941-C4SMFRJSCT0W0BB2 (or mouser 630-HLMP-1301)
101 | terminal block 2 pos |8 |mouser 845-30.702 (ou mouser 651-1729128)
102 | terminal block 3 pos |1 |mouser 845-30.703 (ou mouser 651-1729131)
103 | headers |2 |mouser 855-M20-7821546
104 | high speed optocoupler |1 |mouser 630-6N137-000E
105 | R 200 ohm |4 |mouser 71-CCF50-200
106 | diode shottky |1 |mouser 833-SR108-TP
107 |
108 |
109 |
110 | 
111 |
112 | Le reprogrammer
113 | ===============
114 |
115 | Si vous etes familier avec la programmation d'un Arduino, vous pouvez le reprogrammer pour faire ce que bon vous semble. Et c'est toute la beauté de la chose! Voici les sources que j'utilise: [dccduino.ino](arduinoSource/dccduino/dccduino.ino)
116 |
117 | C'est basé sur la librairie dc de Minabay, Et donc vous allez devoir installer: https://github.com/MynaBay/DCC_Decoder
118 |
119 |
120 |
121 | L'etendre
122 | =========
123 |
124 | Si vous souhaitez developper votre propre decodeur dcc, je fournis aussi les sources Eagle: [arduinoDcc1.3.sch](arduinoDcc1.3.sch) et [arduinoDcc1.3.brd](arduinoDcc1.3.brd)
125 |
126 | Adaptez comme bon vous semble ces sources, pour coller à vos besoins. Mais je les fournis "as is", je peux repondre à quelques questions, mais si vous commencez à changer le layout, vous devez normalement savoir ce que vous faites, je ne pourrais surement pas vous aider à debugger si ca ne marche pas.
127 |
128 | 
129 |
130 | Licence
131 | =======
132 | Le code arduino et les schemas Eagle sont sous licence [GPL v2](gpl-2.0.txt)
133 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | View this project on [CADLAB.io](https://cadlab.io/node/817).
2 |
3 | A versatile Arduino stationary dcc decoder
4 | ==========================================
5 |
6 | 
7 |
8 | When constructing my dcc based train model, I looked for dcc decoder to pilot light (SMD 0402, or standard led), but had difficulty to program them for custom scenario (blinking, road works style, …). There are also some DIY dcc decoder (opendcc decoder) but didn’t manage to make them working. So I decided to create my own stationary dcc decoder based on Arduino (nano), to be able to reprogram it at wish.
9 |
10 | This decoder is pretty simple, you can
11 | * assign it a dcc address (via a learning switch button)
12 | * connect LED lights, or a relay
13 | * choose the light mode if you connected lights. There are 3 different modes you can choose via a push button: constant light (on or off), flicker mode, or 3 way road work lights mode
14 |
15 | It has been designed to be powered by a 16V AC, but can be as well be powered via DCC signal (15v or 18v), or a DC signal.
16 |
17 | Using it
18 | ========
19 |
20 | 
21 |
22 | Powering
23 | --------
24 | This decoder is designed to be powered by a 16V AC power source. It is possible to power it with the dcc signal, but my circuit is not the most power efficient stationary decoder (due to the fact that it power lights, an arduino and eventually a relay), so you don’t want that, except in rare situation.
25 |
26 | This is why there are 2 set of cables:
27 | * one for the 16V AC
28 | * one for the DCC signal
29 |
30 | Assign a dcc address
31 | --------------------
32 |
33 | To assign a dcc address, you have to use the learning switch opposite to the Arduino.
34 | In that position, each time it see a stationary decoder command coming on, it will store it as its new address (and will acknowledge that by blinking the status led).
35 | So to assign a dcc address you just have to
36 | * push the learning switch opposite to the Arduino.
37 | * send a command with the wished address
38 | * you will see the status led blinking, stating that it saw the address and learned it
39 | * push back the learning switch towards the Arduino
40 |
41 |
42 | Connect light
43 | -------------
44 |
45 | On the bottom of the card, you have 3 slots for leds. The + of the led must be on the left. Normaly you can connect only one led per slot (due to the nominal tension that each led has, 2 different led don't have the exact same nominal tension).
46 |
47 | If you use the push button, you will circle between 3 modes:
48 | * constantly on (or off)
49 | * flickering seldomly
50 | * 3 way road work lights (it will switch on the first light, then the second light, then the 3rd light, and cycle again to the first light)
51 |
52 | You just has to use the push button to cycle between the 3 modes. The little status led, will tell you in which mode you are.
53 |
54 |
55 | Connect relay
56 | -------------
57 |
58 | Close to the lights there is a block of 3 pins for the relay (if you decide to build it), which are in this order: low ouput, input, high output.
59 | So the one on the middle is your input (whatever your input is), and the relay will connect it either to the left pin or to the right pin.
60 |
61 | Connect to the other IO
62 | =======================
63 |
64 | 
65 |
66 | There are some generic IO available, that expose
67 | * 5v and ground
68 | * analog pins 6 and 7
69 | * and digital pins 6 and 7
70 |
71 | You can use them at your own advantage, but you will need to reprogram the Arduino to you own purpose: I didn’t program anything on them.
72 |
73 | Assemble it
74 | ===========
75 |
76 | If you don’t want to assemble, or just want the PCB already fabricated, contact me, and I can provide it for you: nicolas.zin@gmail.com
77 |
78 | If you prefer to fully assemble it, you will need to get the PCB, and of course the components.
79 | The PCB gerber files are here: https://github.com/nzin/arduinodcc/blob/master/arduinov1.3.zip (for the eagle source check below)
80 |
81 | To fully assemble it, the full Bill Of Material is:
82 |
83 |
84 | item |how many |ref
85 | ------------------------|---------|------------------------------------
86 | arduino nano |1 |aliexpress
87 | bridge rectifier |1 |mouser 625-B40C800G-E4 (or 625-B380C800G-E4)
88 | capa 330uF |1 |mouser 667-EEU-FM1C331
89 | capa 10uF |1 |mouser 581-TAP106K025SCS
90 | DC-DC converter (9VDC) |1 |mouser 490-V7809-1000 (or cheaper: voltage regulator mouser 511-L7809CV but buy also a heatsink!!)
91 | R 50 ohm |1 |mouser 71-CPF150R000FEE14
92 | relay |1 |sparkfun COM-00100
93 | diode 4004 |1 |mouser 512-1N4004 (or 625-1N4004-E3/54)
94 | transistor 2n2222 |1 |mouser 610-2N2222
95 | R 10k ohm |5 |mouser 71-CCF50-10K
96 | R 1k ohm |1 |mouser 603-CFR-12JR-521K
97 | diode 4148 |1 |mouser 512-1N4148
98 | toggle button |1 |sparkfun COM-00102 (maybe mouser 633-SS12SDP2)
99 | push button |1 |SPARKUN COM-00097 (ou mouser 693-1301.9308)
100 | led |1 |mouser 941-C4SMFRJSCT0W0BB2 (or mouser 630-HLMP-1301)
101 | terminal block 2 pos |8 |mouser 651-1729128
102 | terminal block 3 pos |1 |mouser 651-1729131
103 | headers |2 |mouser 855-M20-7821546
104 | high speed optocoupler |1 |mouser 630-6N137-000E
105 | R 200 ohm |4 |mouser 71-CCF50-200
106 | shottky diode |1 |mouser 833-SR108-TP
107 |
108 |
109 | 
110 |
111 | Reprogram it
112 | ============
113 |
114 | If you are familiar with Arduino programming, you can re-program it to whatever needs you have. That the beauty of it. Here are the arduino sources: https://github.com/nzin/arduinodcc/blob/master/arduinoSource/dccduino.ino
115 |
116 | It is based on the dcc decoder library from Minabay: https://github.com/MynaBay/DCC_Decoder (included in the arduinoSource/dccduino directory)
117 |
118 |
119 |
120 | Extend it
121 | =========
122 |
123 | If you want to develop your own dcc decoder, I provide you the eagle source: https://github.com/nzin/arduinodcc/blob/master/arduinoDcc1.3.sch and https://github.com/nzin/arduinodcc/blob/master/arduinoDcc1.3.brd
124 |
125 | Feel free to adapt it to your needs, but I provide it as is, i.e. I can answer some question but if you decide to change the layout, you are on your own
126 |
127 | 
128 |
129 | Licence
130 | =======
131 | The Arduino code and the Eagle schema are under the [GPL v2](https://github.com/nzin/arduinodcc/blob/master/gpl-2.0.txt)
132 |
--------------------------------------------------------------------------------
/arduinoDcc1.3.brd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | dccarduino v1.3
133 | nicolas.zin@gmail.com
134 | 16VAC
135 | DCC
136 | 5V
137 | 0V
138 | A7 A6
139 | D7 D6
140 | LightD11
141 | - +
142 | LightD10
143 | - +
144 | LightD9
145 | - +
146 | Relai
147 |
148 |
149 |
150 | <b>Opto Couplers</b><p>
151 | Siemens, Hewlett-Packard, Texas Instuments, Sharp, Motorola<p>
152 | <author>Created by librarian@cadsoft.de</author>
153 |
154 |
155 | <b>Dual In Line Package</b>
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | >NAME
171 | >VALUE
172 |
173 |
174 |
175 |
176 | Default symbols for import LTspice schematics<p>
177 | 2012-10-29 alf@cadsoft.de<br>
178 |
179 |
180 | <b>RESISTOR</b><p>
181 | type 0207, grid 10 mm
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 | >NAME
205 | >VALUE
206 |
207 |
208 | <b>RESISTOR</b><p>
209 | type 0204, grid 7.5 mm
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 | >NAME
233 | >VALUE
234 |
235 |
236 |
237 |
238 | <b>Diodes</b><p>
239 | Based on the following sources:
240 | <ul>
241 | <li>Motorola : www.onsemi.com
242 | <li>Fairchild : www.fairchildsemi.com
243 | <li>Philips : www.semiconductors.com
244 | <li>Vishay : www.vishay.de
245 | </ul>
246 | <author>Created by librarian@cadsoft.de</author>
247 |
248 |
249 | <B>DIODE</B><p>
250 | diameter 2 mm, horizontal, grid 7.62 mm
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 | >NAME
271 | >VALUE
272 |
273 |
274 |
275 |
276 |
277 | <B>DIODE</B><p>
278 | diameter 2.54 mm, horizontal, grid 10.16 mm
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 | >NAME
295 | >VALUE
296 |
297 |
298 |
299 |
300 |
301 | <b>DO41</b> 7.6mm x 2mm<p>
302 | Source: http://www.diodes.com/datasheets/ds23001.pdf
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 | >NAME
319 | >VALUE
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 | >NAME
368 | >VALUE
369 |
370 |
371 |
372 |
373 | <h3>SparkFun Electronics' preferred foot prints</h3>
374 | In this library you'll find anything that moves- switches, relays, buttons, potentiometers. Also, anything that goes on a board but isn't electrical in nature- screws, standoffs, etc.<br><br>
375 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
376 | <br><br>
377 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
378 | <br><br>
379 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 | >Name
392 | >Value
393 |
394 |
395 | <b>OMRON SWITCH</b>
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 | >NAME
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 | >NAME
431 | >VALUE
432 |
433 |
434 |
435 |
436 | <b>Transistors</b><p>
437 | <author>Created by librarian@cadsoft.de</author>
438 |
439 |
440 | <b>TO 18</b>
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 | >NAME
455 | >VALUE
456 | 1
457 | 2
458 | 3
459 |
460 |
461 |
462 |
463 | <b>Mounting Holes and Pads</b><p>
464 | <author>Created by librarian@cadsoft.de</author>
465 |
466 |
467 | <b>MOUNTING HOLE</b> 4.1 mm with drill center
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 | <b>Rectifiers</b><p>
484 | General Instrument, Semikron, Diotec, Fagor<p>
485 | <author>Created by librarian@cadsoft.de</author>
486 |
487 |
488 | <b>RECTIFIER</b><p>
489 | 1 A
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 | >NAME
504 | >VALUE
505 |
506 |
507 |
508 |
509 |
510 | <h3>SparkFun Electronics' preferred foot prints</h3>
511 | In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br>
512 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
513 | <br><br>
514 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
515 | <br><br>
516 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
517 |
518 |
519 |
520 |
521 |
522 |
523 | >Value
524 | >Name
525 |
526 |
527 |
528 |
529 | <h3>SparkFun Electronics' preferred foot prints</h3>
530 | In this library you'll find discrete LEDs for illumination or indication, but no displays.<br><br>
531 | We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.
532 | <br><br>
533 | <b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/
534 | <br><br>
535 | You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.
536 |
537 |
538 | <B>LED</B><p>
539 | 3 mm, round
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 | >NAME
552 | >VALUE
553 |
554 |
555 |
556 |
557 | <b>Phoenix Connectors</b><p>
558 | Grid 5.08 mm<p>
559 | Based on the previous libraries:
560 | <ul>
561 | <li>pho508a.lbr
562 | <li>pho508b.lbr
563 | <li>pho508c.lbr
564 | <li>pho508d.lbr
565 | <li>pho508e.lbr
566 | </ul>
567 | <author>Created by librarian@cadsoft.de</author>
568 |
569 |
570 | <b>MKDSN 1,5/ 3-5,08</b> Printklemme<p>
571 | Nennstrom: 13,5 A<br>
572 | Nennspannung: 250 V<br>
573 | Rastermaß: 5,08 mm<br>
574 | Polzahl: 3<br>
575 | Anschlussart: Schraubanschluss<br>
576 | Montage: Löten<br>
577 | Anschlussrichtung Leiter/Platine: 0 °<br>
578 | Artikelnummer: 1729131<br>
579 | Source: http://eshop.phoenixcontact.com .. 1729131.pdf
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 | >NAME
646 | >VALUE
647 |
648 |
649 | <b>MKDSN 1,5/ 2-5,08</b> Printklemme<p>
650 | Nennstrom: 13,5 A<br>
651 | Nennspannung: 250 V<br>
652 | Rastermaß: 5,08 mm<br>
653 | Polzahl: 2<br>
654 | Anschlussart: Schraubanschluss<br>
655 | Montage: Löten<br>
656 | Anschlussrichtung Leiter/Platine: 0 °<br>
657 | Artikelnummer: 1729128<br>
658 | Source: http://eshop.phoenixcontact.com .. 1729128.pdf
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 | >NAME
713 | >VALUE
714 |
715 |
716 |
717 |
718 | <b>Linear Devices</b><p>
719 | Operational amplifiers, comparators, voltage regulators, ADCs, DACs, etc.<p>
720 | <author>Created by librarian@cadsoft.de</author>
721 |
722 |
723 | <b>TO 200 vertical</b>
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 | >NAME
734 | >VALUE
735 | 1
736 | 2
737 | 3
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 | <b>EAGLE Design Rules</b>
760 | <p>
761 | Die Standard-Design-Rules sind so gewählt, dass sie für
762 | die meisten Anwendungen passen. Sollte ihre Platine
763 | besondere Anforderungen haben, treffen Sie die erforderlichen
764 | Einstellungen hier und speichern die Design Rules unter
765 | einem neuen Namen ab.
766 | <b>EAGLE Design Rules</b>
767 | <p>
768 | The default Design Rules have been set to cover
769 | a wide range of applications. Your particular design
770 | may have different requirements, so please make the
771 | necessary adjustments and save your customized
772 | design rules under a new name.
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1055 |
1056 |
1057 |
1058 |
1059 |
1060 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
1070 |
1071 |
1072 |
1073 |
1074 |
1075 |
1076 |
1077 |
1078 |
1079 |
1080 |
1081 |
1082 |
1083 |
1084 |
1085 |
1086 |
1087 |
1088 |
1089 |
1090 |
1091 |
1092 |
1093 |
1094 |
1095 |
1096 |
1097 |
1098 |
1099 |
1100 |
1101 |
1102 |
1103 |
1104 |
1105 |
1106 |
1107 |
1108 |
1109 |
1110 |
1111 |
1112 |
1113 |
1114 |
1115 |
1116 |
1117 |
1118 |
1119 |
1120 |
1121 |
1122 |
1123 |
1124 |
1125 |
1126 |
1127 |
1128 |
1129 |
1130 |
1131 |
1132 |
1133 |
1134 |
1135 |
1136 |
1137 |
1138 |
1139 |
1140 |
1141 |
1142 |
1143 |
1144 |
1145 |
1146 |
1147 |
1148 |
1149 |
1150 |
1151 |
1152 |
1153 |
1154 |
1155 |
1156 |
1157 |
1158 |
1159 |
1160 |
1161 |
1162 |
1163 |
1164 |
1165 |
1166 |
1167 |
1168 |
1169 |
1170 |
1171 |
1172 |
1173 |
1174 |
1175 |
1176 |
1177 |
1178 |
1179 |
1180 |
1181 |
1182 |
1183 |
1184 |
1185 |
1186 |
1187 |
1188 |
1189 |
1190 |
1191 |
1192 |
1193 |
1194 |
1195 |
1196 |
1197 |
1198 |
1199 |
1200 |
1201 |
1202 |
1203 |
1204 |
1205 |
1206 |
1207 |
1208 |
1209 |
1210 |
1211 |
1212 |
1213 |
1214 |
1215 |
1216 |
1217 |
1218 |
1219 |
1220 |
1221 |
1222 |
1223 |
1224 |
1225 |
1226 |
1227 |
1228 |
1229 |
1230 |
1231 |
1232 |
1233 |
1234 |
1235 |
1236 |
1237 |
1238 |
1239 |
1240 |
1241 |
1242 |
1243 |
1244 |
1245 |
1246 |
1247 |
1248 |
1249 |
1250 |
1251 |
1252 |
1253 |
1254 |
1255 |
1256 |
1257 |
1258 |
1259 |
1260 |
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 |
1268 |
1269 |
1270 |
1271 |
1272 |
1273 |
1274 |
1275 |
1276 |
1277 |
1278 |
1279 |
1280 |
1281 |
1282 |
1283 |
1284 |
1285 |
1286 |
1287 |
1288 |
1289 |
1290 |
1291 |
1292 |
1293 |
1294 |
1295 |
1296 |
1297 |
1298 |
1299 |
1300 |
1301 |
1302 |
1303 |
1304 |
1305 |
1306 |
1307 |
1308 |
1309 |
1310 |
1311 |
1312 |
1313 |
1314 |
1315 |
1316 |
1317 |
1318 |
1319 |
1320 |
1321 |
1322 |
1323 |
1324 |
1325 |
1326 |
1327 |
1328 |
1329 |
1330 |
1331 |
1332 |
1333 |
1334 |
1335 |
1336 |
1337 |
1338 |
1339 |
1340 |
1341 |
1342 |
1343 |
1344 |
1345 |
1346 |
1347 |
1348 |
1349 |
1350 |
1351 |
1352 |
1353 |
1354 |
1355 |
1356 |
1357 |
1358 |
1359 |
1360 |
1361 |
1362 |
1363 |
1364 |
1365 |
1366 |
1367 |
1368 |
1369 |
1370 |
1371 |
1372 |
1373 |
1374 |
1375 |
1376 |
1377 |
1378 |
1379 |
1380 |
1381 |
1382 |
1383 |
1384 |
1385 |
1386 |
1387 |
1388 |
1389 |
1390 |
1391 |
1392 |
1393 |
1394 |
1395 |
1396 |
1397 |
1398 |
1399 |
1400 |
1401 |
1402 |
1403 |
1404 |
1405 |
1406 |
1407 |
1408 |
1409 |
1410 |
1411 |
1412 |
1413 |
1414 |
1415 |
1416 |
1417 |
1418 |
1419 |
1420 |
1421 |
1422 |
1423 |
1424 |
1425 |
1426 |
1427 | Since Version 6.2.2 text objects can contain more than one line,
1428 | which will not be processed correctly with this version.
1429 |
1430 |
1431 |
1432 |
--------------------------------------------------------------------------------
/arduinoSource/dccduino/DCC_Decoder.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // DCC_Decoder.cpp - Arduino library for NMRA DCC Decoding.
3 | // Written by Kevin Snow, MynaBay.com, November, 2011.
4 | // Questions: dcc@mynabay.com
5 | // Released into the public domain.
6 | //
7 |
8 | #include "Arduino.h"
9 | #include "DCC_Decoder.h"
10 |
11 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
13 | //
14 | // Global Decoder object
15 | //
16 |
17 | DCC_Decoder DCC;
18 |
19 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
20 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
21 | //
22 | // NMRA DCC Definitions
23 | //
24 | // Microsecond 0 & 1 timings
25 | #define kONE_Min 52
26 | #define kONE_Max 64
27 |
28 | #define kZERO_Min 90
29 | #define kZERO_Max 10000
30 |
31 | // Minimum preamble length
32 | #define kPREAMBLE_MIN 10
33 |
34 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
35 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 | //
37 | // Interrupt handling
38 | //
39 | unsigned long DCC_Decoder::gInterruptMicros = 0;
40 | byte DCC_Decoder::gInterruptTimeIndex = 0;
41 | volatile unsigned int DCC_Decoder::gInterruptTime[2];
42 | volatile unsigned int DCC_Decoder::gInterruptChaos;
43 |
44 | ///////////////////////////////////////////////////
45 |
46 | void DCC_Decoder::DCC_Interrupt()
47 | {
48 | unsigned long ms = micros();
49 | gInterruptTime[gInterruptTimeIndex] = ms - gInterruptMicros;
50 | gInterruptMicros = ms;
51 | gInterruptChaos += gInterruptTimeIndex;
52 | gInterruptTimeIndex ^= 0x01;
53 | }
54 |
55 | ///////////////////////////////////////////////////
56 |
57 | void DCC_Decoder::ShiftInterruptAlignment()
58 | {
59 | noInterrupts();
60 | gInterruptTime[0] = gInterruptTime[1];
61 | gInterruptTimeIndex = 1;
62 | interrupts();
63 | }
64 |
65 | ///////////////////////////////////////////////////
66 |
67 | void DCC_Decoder::StartInterrupt(byte interrupt)
68 | {
69 | gInterruptTimeIndex = 0;
70 | gInterruptTime[0] = gInterruptTime[1] = 0;
71 | gInterruptChaos = 0;
72 | gInterruptMicros = micros();
73 |
74 | attachInterrupt( interrupt, DCC_Interrupt, CHANGE );
75 | }
76 |
77 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
79 | //
80 | // Globals
81 | //
82 | typedef void(*StateFunc)();
83 |
84 | // Current state function pointer
85 | StateFunc DCC_Decoder::gState; // Current state function pointer
86 |
87 | // Timing data from last interrupt
88 | unsigned int DCC_Decoder::gLastChaos; // Interrupt chaos count we processed
89 |
90 | // Preamble bit count
91 | int DCC_Decoder::gPreambleCount; // Bit count for reading preamble
92 |
93 | // Reset reason
94 | byte DCC_Decoder::gResetReason; // Result code of last reason decoder was reset
95 | boolean DCC_Decoder::gHandledAsRawPacket;
96 |
97 | // Packet data
98 | byte DCC_Decoder::gPacket[kPACKET_LEN_MAX]; // The packet data.
99 | byte DCC_Decoder::gPacketIndex; // Byte index to write to.
100 | byte DCC_Decoder::gPacketMask; // Bit index to write to. 0x80,0x40,0x20,...0x01
101 | boolean DCC_Decoder::gPacketEndedWith1; // Set true if packet ended on 1. Spec requires that the
102 | // packet end bit can count as a bit in next preamble.
103 | // CV Storage
104 | byte DCC_Decoder::gCV[kCV_MAX]; // CV Storage (TODO - Move to PROGMEM)
105 |
106 | // Packet arrival timing
107 | unsigned long DCC_Decoder::gThisPacketMS; // Milliseconds of this packet being parsed
108 | boolean DCC_Decoder::gLastPacketToThisAddress; // Was last pack processed to this decoder's address?
109 |
110 | unsigned long DCC_Decoder::gLastValidPacketMS; // Milliseconds of last valid packet
111 | unsigned long DCC_Decoder::gLastValidPacketToAddressMS; // Milliseconds of last valid packet to this decoder
112 | unsigned long DCC_Decoder::gLastValidIdlePacketMS; // Milliseconds of last valid idle packet
113 | unsigned long DCC_Decoder::gLastValidResetPacketMS; // Milliseconds of last valid reset packet
114 |
115 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
116 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
117 | //
118 | // Packet Timing Support
119 | //
120 | unsigned long DCC_Decoder::MillisecondsSinceLastValidPacket()
121 | {
122 | return millis() - gLastValidPacketMS;
123 | }
124 |
125 | unsigned long DCC_Decoder::MillisecondsSinceLastPacketToThisDecoder()
126 | {
127 | return millis() - gLastValidPacketToAddressMS;
128 | }
129 |
130 | unsigned long DCC_Decoder::MillisecondsSinceLastIdlePacket()
131 | {
132 | return millis() - gLastValidIdlePacketMS;
133 | }
134 |
135 | unsigned long DCC_Decoder::MillisecondsSinceLastResetPacket()
136 | {
137 | return millis() - gLastValidResetPacketMS;
138 | }
139 |
140 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
141 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
142 | //
143 | // CV Support
144 | //
145 | byte DCC_Decoder::ReadCV(int cv)
146 | {
147 | if( cv>=kCV_PrimaryAddress && cv=kCV_PrimaryAddress && cv 3 ) errorDectection ^= gPacket[2];
278 | if( gPacketIndex > 4 ) errorDectection ^= gPacket[3];
279 | if( gPacketIndex > 5 ) errorDectection ^= gPacket[4];
280 | if( errorDectection != gPacket[gPacketIndex-1] )
281 | {
282 | GOTO_DecoderReset( kDCC_ERR_DETECTION_FAILED );
283 | }
284 |
285 | // Save off milliseconds of this valid packet
286 | gThisPacketMS = millis();
287 | gLastPacketToThisAddress = false;
288 |
289 | ///////////////////////////////////////////////////////////
290 | // Dispatch to RawPacketHandler - All packets go to raw (except idle and reset above)
291 | //
292 | // gHandledAsRawPacket cleared in Reset. If packet is handled here this flag avoids
293 | // sending to another dispatch routine. We don't just return here because we need to
294 | // figure out packet type and update time fields.
295 | if( func_RawPacket )
296 | {
297 | gHandledAsRawPacket = (func_RawPacket)(gPacketIndex,gPacket);
298 | }
299 |
300 | ///////////////////////////////////////////////////////////
301 | ///////////////////////////////////////////////////////////
302 | // Handle 3 byte packets
303 | if( gPacketIndex == 3 )
304 | {
305 | ///////////////////////////////////////////////////////////
306 | // Decoder idle & reset packets as defined in 9.2.
307 | if( gPacket[1]==0x00 )
308 | {
309 | // Broadcast idle packet
310 | if( gPacket[0]==0xFF )
311 | {
312 | if( !gHandledAsRawPacket && func_IdlePacket )
313 | {
314 | (func_IdlePacket)(gPacketIndex,gPacket);
315 | }
316 | GOTO_DecoderReset( kDCC_OK_IDLE );
317 | }else{
318 | // Broadcast reset packet
319 | if( gPacket[0]==0x00 )
320 | {
321 | if( !gHandledAsRawPacket && func_ResetPacket )
322 | {
323 | (func_ResetPacket)(gPacketIndex,gPacket);
324 | }
325 | GOTO_DecoderReset( kDCC_OK_RESET );
326 | }
327 | }
328 | }
329 |
330 | ///////////////////////////////////////////////////////////
331 | // Handle as a basic accessory decoder packet
332 | if( ((gPacket[0] & 0xC0) == 0x80) && ((gPacket[1] & 0x80) == 0x80) )
333 | {
334 | address = ~gPacket[1] & 0x70;
335 | address = (address<<2) + (gPacket[0] & 0x3F);
336 | gLastPacketToThisAddress = (address==DCC.Address());
337 | if( gLastPacketToThisAddress || address == 0x003F || func_BasicAccPacket_All_Packets ) // 0x003F is broadcast packet
338 | {
339 | if( !gHandledAsRawPacket && func_BasicAccPacket )
340 | {
341 | // Call BasicAccHandler Activate bit data bits
342 | (func_BasicAccPacket)( address, ((gPacket[1] & 0x08) ? true : false), (gPacket[1] & 0x07));
343 | }
344 | }
345 | GOTO_DecoderReset( kDCC_OK_BASIC_ACCESSORY );
346 | }
347 |
348 | ///////////////////////////////////////////////////////////
349 | // Handle as a baseline packet
350 |
351 | // What decoder is this addressed to?
352 | if( gPacket[0] & 0x80 )
353 | {
354 | GOTO_DecoderReset( kDCC_ERR_BASELINE_ADDR );
355 | }
356 |
357 | // Baseline instruction packet?
358 | if( (gPacket[1] & 0xC0) != 0x40 )
359 | {
360 | GOTO_DecoderReset( kDCC_ERR_BASELINE_INSTR );
361 | }
362 |
363 | // bits as defined in 9.2
364 | byte addressByte = gPacket[0] & 0x7F;
365 | byte directionBit = gPacket[1] & 0x20;
366 | byte cBit = gPacket[1] & 0x10;
367 | byte speedBits = gPacket[1] & 0x0F;
368 |
369 | // Stop or estop??
370 | if( speedBits==0 )
371 | {
372 | speedBits = kDCC_STOP_SPEED;
373 | }else{
374 | if( speedBits== 1 )
375 | {
376 | speedBits = kDCC_ESTOP_SPEED;
377 | }else{
378 | if( gCV[kCV_ConfigurationData1] & 0x02 ) // Bit 1 of CV29: 0=14speeds, 1=28Speeds
379 | {
380 | speedBits = ((speedBits << 1 ) & (cBit ? 1 : 0)) - 3; // speedBits = 1..28
381 | }else{
382 | speedBits -= 1; // speedBits = 1..14
383 | }
384 | }
385 | }
386 |
387 | // Make callback
388 | gLastPacketToThisAddress = (addressByte==DCC.ReadCV(kCV_PrimaryAddress));
389 | if( func_BaselineControlPacket_All_Packets || gLastPacketToThisAddress )
390 | {
391 | if( !gHandledAsRawPacket && func_BaselineControlPacket )
392 | {
393 | (*func_BaselineControlPacket)(addressByte,speedBits,directionBit);
394 | }
395 | }
396 | GOTO_DecoderReset( kDCC_OK_BASELINE );
397 | }
398 |
399 | ///////////////////////////////////////////////////////////
400 | ///////////////////////////////////////////////////////////
401 | // Handle 4 byte packets
402 | if( gPacketIndex == 4 )
403 | {
404 | ///////////////////////////////////////////////////////////
405 | // Handle as a extd accessory decoder packet (4 bytes)
406 | if( ((gPacket[0] & 0xC0) == 0x80) && ((gPacket[1] & 0x85) == 0x01) )
407 | {
408 | int msb = (gPacket[1] & 0x06);
409 | address = (gPacket[1] & 0x70);
410 | address = (msb<<8) + (address<<2) + (gPacket[0] & 0x3F);
411 | gLastPacketToThisAddress = (address==DCC.Address());
412 | if( gLastPacketToThisAddress || address == 0x033F || func_ExtdAccPacket_All_Packets ) // 0x033F is broadcast packet
413 | {
414 | if( !gHandledAsRawPacket && func_ExtdAccPacket )
415 | {
416 | // Call ExtAccHandler data bits
417 | (*func_ExtdAccPacket)( address, gPacket[2] & 0x1F);
418 | }
419 | }
420 | GOTO_DecoderReset( kDCC_OK_EXTENDED_ACCESSORY );
421 | }
422 | }
423 |
424 | ///////////////////////////////////////////////////////////
425 | ///////////////////////////////////////////////////////////
426 | // Handle 5 byte packets
427 | if( gPacketIndex == 5 )
428 | {
429 | // TODO - Implement
430 | }
431 |
432 | ///////////////////////////////////////////////////////////
433 | ///////////////////////////////////////////////////////////
434 | // Handle 6 byte packets
435 | if( gPacketIndex == 6 )
436 | {
437 | // TODO - Implement
438 | }
439 |
440 | ///////////////////////////////////////////////////////////
441 | // Done!
442 | GOTO_DecoderReset( kDCC_OK );
443 | }
444 |
445 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
446 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
447 | //
448 | // Standard interrupt reader - If a complete bit has been read it places timing in periodA & periodB and flows out bottom.
449 | //
450 | #define StandardInterruptHeader(behalfOf) \
451 | noInterrupts(); \
452 | if( gInterruptChaos == gLastChaos ) \
453 | { \
454 | interrupts(); \
455 | return; \
456 | } \
457 | if( gInterruptChaos-gLastChaos > 1 ) \
458 | { \
459 | interrupts(); \
460 | GOTO_DecoderReset( kDCC_ERR_MISSED_BITS ); \
461 | } \
462 | unsigned int periodA = gInterruptTime[0]; \
463 | unsigned int periodB = gInterruptTime[1]; \
464 | gLastChaos = gInterruptChaos; \
465 | interrupts(); \
466 | boolean aIs1 = ( periodA >= kONE_Min && periodA <= kONE_Max ); \
467 | if( !aIs1 && (periodA < kZERO_Min || periodA > kZERO_Max) ) \
468 | { \
469 | GOTO_DecoderReset( kDCC_ERR_NOT_0_OR_1 ); \
470 | } \
471 | boolean bIs1 = ( periodB >= kONE_Min && periodB <= kONE_Max ); \
472 | if( !bIs1 && (periodB < kZERO_Min || periodB > kZERO_Max) ) \
473 | { \
474 | GOTO_DecoderReset( kDCC_ERR_NOT_0_OR_1 ); \
475 | } \
476 |
477 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
478 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
479 | //
480 | // Read packet bytes
481 | //
482 | void DCC_Decoder::State_ReadPacket()
483 | {
484 | // Interrupt header
485 | StandardInterruptHeader();
486 |
487 | // Normally the two halves match. If not, reset
488 | if( aIs1 == bIs1 )
489 | {
490 | // 8 out of 9 times through we'll have a mask and be writing bits
491 | if( gPacketMask )
492 | {
493 | // Write the bit.
494 | if( aIs1 )
495 | {
496 | gPacket[gPacketIndex] |= gPacketMask;
497 | }
498 | // advance the bit mask
499 | gPacketMask = gPacketMask >> 1;
500 |
501 | }else{
502 | // Getting here is the 9th time and the it's the data start bit between bytes.
503 | // Zero indicates more data, 1 indicates end of packet
504 |
505 | // Advance index and reset mask
506 | gPacketIndex++;
507 | gPacketMask = 0x80;
508 |
509 | // Data start bit is a 1, that's the end of packet! Execute.
510 | if( aIs1 )
511 | {
512 | gPacketEndedWith1 = true;
513 | if( gPacketIndex>=kPACKET_LEN_MIN && gPacketIndex<=kPACKET_LEN_MAX )
514 | {
515 | GOTO_ExecutePacket();
516 | }
517 | GOTO_DecoderReset( kDCC_ERR_INVALID_LENGTH );
518 | }else{
519 | // Data start bit is a 0. Do we have room for more data?
520 | if( gPacketIndex >= kPACKET_LEN_MAX )
521 | {
522 | GOTO_DecoderReset( kDCC_ERR_MISSING_END_BIT );
523 | }
524 | }
525 | }
526 | }else{
527 | GOTO_DecoderReset( kDCC_ERR_NOT_0_OR_1 );
528 | }
529 | }
530 |
531 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
532 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
533 | //
534 | // Watch for Preamble
535 | //
536 | void DCC_Decoder::State_ReadPreamble()
537 | {
538 | // Interrupt header
539 | StandardInterruptHeader();
540 |
541 | // If we get here, booleans aIs1 and bIs1 are set to the two halves of the next bit.
542 |
543 | // If both are 1, it's a 1 bit.
544 | if( aIs1 && bIs1 )
545 | {
546 | // Increment preamble bit count
547 | ++gPreambleCount;
548 | }else{
549 | // If they equal it's a 0.
550 | if( aIs1 == bIs1 )
551 | {
552 | if( gPreambleCount >= kPREAMBLE_MIN )
553 | {
554 | // BANG! Read preamble plus trailing 0. Go read the packet.
555 | GOTO_ReadPacketState();
556 | }
557 | }else{
558 | // One is 0 the other 1. Shift alignment.
559 | ShiftInterruptAlignment();
560 | }
561 | // Not enough bits in preamble or shifted alignment. Start over at zero preamble.
562 | gPreambleCount = 0;
563 | }
564 | }
565 |
566 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
567 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
568 | //
569 | // Reset handling (Part 2)
570 | //
571 | void DCC_Decoder::State_Reset()
572 | {
573 | // EngineReset Handler (Debugging)
574 | if( func_DecodingEngineCompletion )
575 | {
576 | (func_DecodingEngineCompletion)(gHandledAsRawPacket ? kDCC_OK_MAX : gResetReason);
577 | }
578 | gHandledAsRawPacket = false;
579 |
580 | // If reset with an OK code, this was a valid packet. Save off times
581 | if( gResetReason < kDCC_OK_MAX )
582 | {
583 | // Save MS of last valid packet
584 | gLastValidPacketMS = gThisPacketMS;
585 |
586 | // Save off other times
587 | switch( gResetReason )
588 | {
589 | case kDCC_OK_IDLE:
590 | gLastValidIdlePacketMS = gThisPacketMS;
591 | break;
592 | case kDCC_OK_RESET:
593 | gLastValidResetPacketMS = gThisPacketMS;
594 | break;
595 | case kDCC_OK_BASELINE:
596 | case kDCC_OK_BASIC_ACCESSORY:
597 | case kDCC_OK_EXTENDED_ACCESSORY:
598 | if(gLastPacketToThisAddress)
599 | {
600 | gLastValidPacketToAddressMS = gThisPacketMS;
601 | }
602 | break;
603 | default:
604 | break;
605 | }
606 | }
607 |
608 | // Reset packet data
609 | gPacket[0] = gPacket[1] = gPacket[2] = gPacket[3] = gPacket[4] = gPacket[5] = 0;
610 | gPacketIndex = 0;
611 | gPacketMask = 0x80;
612 |
613 | // Copy last time and reset chaos
614 | noInterrupts();
615 | gPreambleCount = (gPacketEndedWith1 && gLastChaos==gInterruptChaos) ? 1 : 0;
616 | gLastChaos = gInterruptChaos = 0;
617 | interrupts();
618 |
619 | // Clear packet ended 1 flag
620 | gPacketEndedWith1 = false;
621 |
622 | // Go find preamble
623 | GOTO_PreambleState();
624 | }
625 |
626 | void DCC_Decoder::State_Boot()
627 | {
628 | }
629 |
630 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
631 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
632 | //
633 | // SetupDecoder
634 | //
635 | void DCC_Decoder::SetupDecoder(byte mfgID, byte mfgVers, byte interrupt)
636 | {
637 | if( gInterruptMicros == 0 )
638 | {
639 | // Save mfg info
640 | gCV[kCV_ManufacturerVersionNo] = mfgID;
641 | gCV[kCV_ManufacturedID] = mfgVers;
642 |
643 | // Attach the DCC interrupt
644 | StartInterrupt(interrupt);
645 |
646 | // Start decoder in reset state
647 | GOTO_DecoderReset( kDCC_OK_BOOT );
648 | }
649 | }
650 |
651 | void DCC_Decoder::SetupMonitor(byte interrupt)
652 | {
653 | if( gInterruptMicros == 0 )
654 | {
655 | // Attach the DCC interrupt
656 | StartInterrupt(interrupt);
657 |
658 | // Start decoder in reset state
659 | GOTO_DecoderReset( kDCC_OK_BOOT );
660 | }
661 | }
662 |
663 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
664 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
665 | //
666 | // Hearbeat function. Dispatch the dcc_decoder library state machine.
667 | //
668 | void DCC_Decoder::loop()
669 | {
670 | (gState)();
671 | }
672 |
673 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
674 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
675 | //
676 | // Constructor (Not really).
677 | //
678 | DCC_Decoder::DCC_Decoder()
679 | {
680 | gState = DCC_Decoder::State_Boot;
681 | }
682 |
683 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
684 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
685 | //
686 | // Human readable error strings
687 | //
688 |
689 | const char PROGMEM*
690 | DCC_Decoder::ResultString(byte resultCode)
691 | {
692 | static const char PROGMEM* const gResults[] =
693 | {
694 | "OK",
695 | "OK - Unhandled",
696 | "OK - Boot",
697 | "OK - Idle packet",
698 | "OK - Reset packet",
699 | "OK - Handled raw",
700 | "OK - Handled baseline",
701 | "OK - Handled basic accessory",
702 | "OK - Handled extended accessory",
703 | };
704 |
705 | static const char PROGMEM* const gErrors[] =
706 | {
707 | "ERROR - Detection failed",
708 | "ERROR - Baseline address",
709 | "ERROR - Baseline instruction",
710 | "ERROR - Missed bits",
711 | "ERROR - Not 0 or 1",
712 | "ERROR - Invalid packet length",
713 | "ERROR - Missing packet end bits",
714 | };
715 |
716 | static const char PROGMEM* const gErrorsBadCode = "ERROR - Bad result code";
717 |
718 | if( resultCode>=0 && resultCode<(sizeof(gResults)/sizeof(gResults[0])) )
719 | {
720 | return gResults[resultCode];
721 | }
722 | if( resultCode>=100 && (resultCode-100)<(byte)(sizeof(gErrors)/sizeof(gErrors[0])) )
723 | {
724 | return gErrors[resultCode-100];
725 | }
726 | return gErrorsBadCode;
727 | }
728 |
729 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
730 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
731 | //
732 | // Helper to make packet strings
733 | //
734 | char* DCC_Decoder::MakePacketString(char* buffer60Bytes, byte byteCount, byte* packet)
735 | {
736 | buffer60Bytes[0] = 0;
737 | if( byteCount>=kPACKET_LEN_MIN && byteCount<=kPACKET_LEN_MAX )
738 | {
739 | int i = 0;
740 | for(byte byt=0; byt>1;
747 | }
748 | buffer60Bytes[i++] = ' ';
749 | }
750 | buffer60Bytes[--i] = 0;
751 | }
752 | return buffer60Bytes;
753 | }
754 |
755 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
756 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
757 | //
758 | // Helper to return preamble length
759 | //
760 | int DCC_Decoder::LastPreambleBitCount()
761 | {
762 | return gPreambleCount;
763 | }
764 |
765 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
766 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
767 |
--------------------------------------------------------------------------------
/arduinoSource/dccduino/DCC_Decoder.h:
--------------------------------------------------------------------------------
1 | //
2 | // DCC_Decoder.h - Arduino library for NMRA DCC Decoding.
3 | // Written by Kevin Snow, MynaBay.com, November, 2011.
4 | // Questions: dcc@mynabay.com
5 | // Released into the public domain.
6 | //
7 |
8 | #ifndef __DCC_DECODER_H__
9 | #define __DCC_DECODER_H__
10 |
11 | #include "Arduino.h"
12 |
13 | ///////////////////////////////////////////////////////////////////////////////////////
14 |
15 | #define kDCC_STOP_SPEED 0xFE
16 | #define kDCC_ESTOP_SPEED 0xFF
17 |
18 | // Multifunction Decoders
19 | #define kCV_PrimaryAddress 1
20 | #define kCV_Vstart 2
21 | #define kCV_AccelerationRate 3
22 | #define kCV_Deceleration Rate 4
23 | #define kCV_ManufacturerVersionNo 7
24 | #define kCV_ManufacturedID 8
25 | #define kCV_ExtendedAddress1 17
26 | #define kCV_ExtendedAddress2 18
27 | #define kCV_ConfigurationData1 29
28 |
29 | // Accessory Decoders
30 | #define kCV_AddressLSB 1
31 | #define kCV_AddressMSB 9
32 |
33 |
34 | // DCC_Decoder results/errors
35 | #define kDCC_OK 0
36 | #define kDCC_OK_UNHANDLED 1
37 | #define kDCC_OK_BOOT 2
38 | #define kDCC_OK_IDLE 3
39 | #define kDCC_OK_RESET 4
40 | #define kDCC_OK_RAW 5
41 | #define kDCC_OK_BASELINE 6
42 | #define kDCC_OK_BASIC_ACCESSORY 7
43 | #define kDCC_OK_EXTENDED_ACCESSORY 8
44 | #define kDCC_OK_MAX 99
45 |
46 | #define kDCC_ERR_DETECTION_FAILED 100
47 | #define kDCC_ERR_BASELINE_ADDR 101
48 | #define kDCC_ERR_BASELINE_INSTR 102 // Baseline packet instruction isn't 0x01DCSSSS
49 | #define kDCC_ERR_MISSED_BITS 103
50 | #define kDCC_ERR_NOT_0_OR_1 104
51 | #define kDCC_ERR_INVALID_LENGTH 105
52 | #define kDCC_ERR_MISSING_END_BIT 106
53 |
54 | // Min and max valid packet lengths
55 | #define kPACKET_LEN_MIN 3
56 | #define kPACKET_LEN_MAX 6
57 |
58 | // CV 1..256 are supported
59 | #define kCV_MAX 257
60 |
61 | ///////////////////////////////////////////////////////////////////////////////////////
62 |
63 | typedef boolean (*RawPacket)(byte byteCount, byte* packetBytes);
64 |
65 | typedef void (*IdleResetPacket)(byte byteCount, byte* packetBytes);
66 |
67 | typedef void (*BaselineControlPacket)(int address, int speed, int direction);
68 |
69 | typedef void (*BasicAccDecoderPacket)(int address, boolean activate, byte data);
70 | typedef void (*ExtendedAccDecoderPacket)(int address, byte data);
71 |
72 | typedef void (*DecodingEngineCompletion)(byte resultOfLastPacket);
73 |
74 | ///////////////////////////////////////////////////////////////////////////////////////
75 |
76 | typedef void(*StateFunc)();
77 |
78 | ///////////////////////////////////////////////////////////////////////////////////////
79 |
80 | class DCC_Decoder
81 | {
82 | public:
83 | DCC_Decoder();
84 |
85 | // Called from setup in Arduino Sketch. Set mfgID, mfgVers and interrupt. Call one SetupXXX
86 | void SetupDecoder(byte mfgID, byte mfgVers, byte interrupt); // Used for Decoder
87 | void SetupMonitor(byte interrupt); // Used when building a monitor
88 |
89 | // All packets are sent to RawPacketHandler. Return true to stop dispatching to other handlers.
90 | void SetRawPacketHandler(RawPacket func);
91 |
92 | // S 9.2 defines two special packets. Idle and reset.
93 | void SetIdlePacketHandler(IdleResetPacket func);
94 | void SetResetPacketHandler(IdleResetPacket func);
95 |
96 | // Handler for S 9.2 baseline packets. Speed value will be 1-14, 1-28, kDCC_STOP_SPEED or kDCC_ESTOP_SPEED
97 | void SetBaselineControlPacketHandler(BaselineControlPacket func, boolean allPackets);
98 |
99 | // Handler for RP 9.2.1 Accessory Decoders.
100 | void SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket func, boolean allPackets);
101 | void SetExtendedAccessoryDecoderPacketHandler(ExtendedAccDecoderPacket func, boolean allPackets);
102 |
103 | // Read/Write CVs
104 | byte ReadCV(int cv);
105 | void WriteCV(int cv, byte data);
106 |
107 | // Helper function to read decoder address
108 | int Address();
109 |
110 | // Call at least once from mainloop. Not calling frequently enough and library will miss data bits!
111 | void loop();
112 |
113 | // Returns the packet data in string form.
114 | char* MakePacketString(char* buffer60Bytes, byte packetByteCount, byte* packet);
115 |
116 | // Returns the number of bits in last preamble
117 | int LastPreambleBitCount();
118 |
119 | // Timing functions. These return MS since various packets
120 | unsigned long MillisecondsSinceLastValidPacket();
121 | unsigned long MillisecondsSinceLastPacketToThisDecoder();
122 | unsigned long MillisecondsSinceLastIdlePacket();
123 | unsigned long MillisecondsSinceLastResetPacket();
124 |
125 |
126 | //======================= Debugging =======================//
127 | // Everytime the DCC Decoder engine starts looking for preamble bits this will be
128 | // called with result of last packet. (Debugging)
129 | void SetDecodingEngineCompletionStatusHandler(DecodingEngineCompletion func);
130 | // Converts code passed into completionStatusHandler to human readable string.
131 | const char PROGMEM* ResultString(byte resultCode);
132 |
133 | //======================= Library Internals =======================//
134 | private:
135 | // State machine functions
136 | static void State_Boot();
137 | static void State_ReadPreamble();
138 | static void State_ReadPacket();
139 | static void State_Execute();
140 | static void State_Reset();
141 |
142 | // Function pointers for the library callbacks
143 | static RawPacket func_RawPacket;
144 | static IdleResetPacket func_IdlePacket;
145 | static IdleResetPacket func_ResetPacket;
146 |
147 | static BasicAccDecoderPacket func_BasicAccPacket;
148 | static boolean func_BasicAccPacket_All_Packets;
149 | static ExtendedAccDecoderPacket func_ExtdAccPacket;
150 | static boolean func_ExtdAccPacket_All_Packets;
151 |
152 | static BaselineControlPacket func_BaselineControlPacket;
153 | static boolean func_BaselineControlPacket_All_Packets;
154 |
155 | static DecodingEngineCompletion func_DecodingEngineCompletion;
156 |
157 | // Current state function pointer
158 | static StateFunc gState; // Current state function pointer
159 |
160 | // Timing data from last interrupt
161 | static unsigned int gLastChaos; // Interrupt chaos count we processed
162 |
163 | // Preamble bit count
164 | static int gPreambleCount; // Bit count for reading preamble
165 |
166 | // Reset reason
167 | static byte gResetReason; // Result code of last reason decoder was reset
168 | static boolean gHandledAsRawPacket;
169 |
170 | // Packet data
171 | static byte gPacket[kPACKET_LEN_MAX]; // The packet data.
172 | static byte gPacketIndex; // Byte index to write to.
173 | static byte gPacketMask; // Bit index to write to. 0x80,0x40,0x20,...0x01
174 | static boolean gPacketEndedWith1; // Set true if packet ended on 1. Spec requires that the
175 | // packet end bit can count as a bit in next preamble.
176 | // CV Storage
177 | static byte gCV[kCV_MAX]; // CV Storage (TODO - Storage in PROGMEM)
178 |
179 | // Packet arrival timing
180 | static unsigned long gThisPacketMS; // Milliseconds of this packet being parsed
181 | static boolean gLastPacketToThisAddress; // Was last pack processed to this decoder's address?
182 |
183 | static unsigned long gLastValidPacketMS; // Milliseconds of last valid packet
184 | static unsigned long gLastValidPacketToAddressMS; // Milliseconds of last valid packet to this decoder
185 | static unsigned long gLastValidIdlePacketMS; // Milliseconds of last valid idle packet
186 | static unsigned long gLastValidResetPacketMS; // Milliseconds of last valid reset packet
187 |
188 | //////////////////////////////////////////////////////
189 | // Interrupt Support
190 | static void StartInterrupt(byte interrupt);
191 | static void DCC_Interrupt();
192 | static void ShiftInterruptAlignment();
193 |
194 | static unsigned long gInterruptMicros;
195 | static byte gInterruptTimeIndex;
196 | static volatile unsigned int gInterruptTime[2];
197 | static volatile unsigned int gInterruptChaos;
198 | };
199 |
200 | ///////////////////////////////////////////////////////////////////////////////////////
201 |
202 | extern DCC_Decoder DCC;
203 |
204 | ///////////////////////////////////////////////////////////////////////////////////////
205 |
206 | #endif
207 |
--------------------------------------------------------------------------------
/arduinoSource/dccduino/dccduino.ino:
--------------------------------------------------------------------------------
1 | #include "DCC_Decoder.h"
2 | #define kDCC_INTERRUPT 0
3 |
4 |
5 | #include
6 | #define EEPROM_LIGHTMODE 0 // we store the last "light mode" selected by the user (via the push button)
7 | #define EEPROM_SWITCHSTATUS 1 // we store the last switch status (send via dcc)
8 | #define EEPROM_ADDRESS 2 // we store our dcc address
9 |
10 | #define LIGHT0 9
11 | #define LIGHT1 10
12 | #define LIGHT2 11
13 | #define LEDCONTROL 12
14 | #define PUSHBUTTON 5
15 | #define LEARNINGBUTTON 3
16 | #define RELAY 4
17 |
18 | #define MAXLIGHTMODE 2 // mode0=continuous, mode1=flicketing, mode2=roundrobin
19 | int lightMode=0;
20 | int switchStatus=HIGH;
21 | int learningMode=LOW;
22 |
23 |
24 |
25 | /**
26 | * this is just a function to show via the onboard PCB led, the state of the decoder
27 | */
28 | void showAcknowledge(int nb) {
29 | for (int i=0;i0) valLight[i]-=5;
61 | }
62 | break;
63 | /*
64 | * mode 1:
65 | * - switch status = HIGH: we switch on the light in a fading in way.
66 | * - switch status = LOW: we switch off the light in a fading off way.
67 | * BUT randomly (1% of the time), we switch off a light and switch on it just after, to flicker it
68 | */
69 | case 1:
70 | if (switchStatus==HIGH) {
71 | for (int i=0;i<3;i++) if (valLight[i]<255) valLight[i]+=5;
72 | } else {
73 | for (int i=0;i<3;i++) if (valLight[i]>0) valLight[i]-=5;
74 | }
75 |
76 | /* 1% chance to flicker 1 of the 3 lights */
77 | if ((blink=random(100))<3) {
78 | tmp=valLight[blink];
79 | valLight[blink]=0;
80 | analogWrite(LIGHT0,valLight[0]);
81 | analogWrite(LIGHT1,valLight[1]);
82 | analogWrite(LIGHT2,valLight[2]);
83 | delay(50);
84 | valLight[blink]=tmp;
85 | }
86 | break;
87 | /*
88 | * mode 2: we switch on the first light, then the second light, then the 3rd light
89 | */
90 | case 2:
91 | chain++;
92 | if (chain==20) {
93 | valLight[0]=0;
94 | valLight[1]=255;
95 | } else if (chain==40) {
96 | valLight[1]=0;
97 | valLight[2]=255;
98 | } else if (chain==60) {
99 | valLight[2]=0;
100 | valLight[0]=255;
101 | chain=0;
102 | }
103 | break;
104 | }
105 | analogWrite(LIGHT0,valLight[0]);
106 | analogWrite(LIGHT1,valLight[1]);
107 | analogWrite(LIGHT2,valLight[2]);
108 | }
109 |
110 |
111 |
112 | /**
113 | * when a DCC packet is received, this function is called
114 | * for our needs, we decode the address:
115 | * - if we are in learning mode, we store this address as our new address
116 | * - if we are in normal mode, we switch on, or off light and relay, depending on the "enable" state command
117 | */
118 | void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
119 | {
120 | // Convert NMRA packet address format to human address
121 | address -= 1;
122 | address *= 4;
123 | address += 1;
124 | address += (data & 0x06) >> 1;
125 |
126 | int enable = (data & 0x01) ? HIGH : LOW;
127 |
128 | // if we are in learning mode, we store our dcc address
129 | if (learningMode==HIGH) {
130 | EEPROM.write(EEPROM_ADDRESS,address%256);
131 | EEPROM.write(EEPROM_ADDRESS+1,address/256);
132 | showAcknowledge(3);
133 | } else {
134 | // if we are in normal mode, then... we act accordingly
135 | int myaddress=EEPROM.read(EEPROM_ADDRESS)+(EEPROM.read(EEPROM_ADDRESS+1)*256);
136 | if (myaddress==address) {
137 | switchStatus=enable;
138 | EEPROM.write(EEPROM_SWITCHSTATUS,switchStatus);
139 | digitalWrite(RELAY,switchStatus);
140 | }
141 | }
142 | }
143 |
144 |
145 |
146 | /*
147 | * standard arduino initialisation function
148 | * we initialize lights, button, and relay pins
149 | */
150 | void setup() {
151 | // put your setup code here, to run once:
152 | pinMode(LIGHT0, OUTPUT);
153 | pinMode(LIGHT1, OUTPUT);
154 | pinMode(LIGHT2, OUTPUT);
155 | pinMode(LEDCONTROL, OUTPUT);
156 | pinMode(PUSHBUTTON, INPUT);
157 | pinMode(LEARNINGBUTTON,INPUT);
158 | pinMode(RELAY,OUTPUT);
159 |
160 | lightMode=EEPROM.read(EEPROM_LIGHTMODE);
161 | if (lightMode>MAXLIGHTMODE) lightMode=0;
162 | switchStatus=EEPROM.read(EEPROM_SWITCHSTATUS);
163 | if (switchStatus!=HIGH && switchStatus!=LOW) switchStatus=HIGH;
164 | digitalWrite(RELAY,switchStatus);
165 |
166 | showAcknowledge(lightMode+1);
167 | randomSeed(analogRead(A3));
168 |
169 | DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
170 | // ConfigureDecoder();
171 | DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
172 | }
173 |
174 |
175 |
176 | void loop() {
177 | static int pushbuttonOldval=0,pushbuttonVal=0;
178 | static int learningbuttonOldval=0,learningbuttonVal=0;
179 | static unsigned long timer=0;
180 |
181 | ////////////////////////////////////////////////////////////////
182 | // Loop DCC library
183 | DCC.loop();
184 |
185 | ////////////////////////////////////////////////////////////////
186 | // check if the push button has been pressed
187 | pushbuttonVal=digitalRead(PUSHBUTTON);
188 | if (pushbuttonVal==LOW && pushbuttonOldval!=pushbuttonVal) {
189 | lightMode++;
190 | if (lightMode>MAXLIGHTMODE) lightMode=0;
191 | EEPROM.write(EEPROM_LIGHTMODE,lightMode);
192 | showAcknowledge(lightMode+1);
193 | }
194 | pushbuttonOldval=pushbuttonVal;
195 |
196 | ////////////////////////////////////////////////////////////////
197 | // check if the learning button has been enabled
198 | learningbuttonVal=digitalRead(LEARNINGBUTTON);
199 | if (learningbuttonOldval!=learningbuttonVal) {
200 | learningMode=learningbuttonVal;
201 | if (learningMode==HIGH) showAcknowledge(3);
202 | }
203 | learningbuttonOldval=learningbuttonVal;
204 |
205 | ////////////////////////////////////////////////////////////////
206 | // check if we have light to change from state
207 | if (millis()-timer>50) {
208 | treatLight(switchStatus,lightMode);
209 | timer=millis();
210 | }
211 | }
212 |
213 |
--------------------------------------------------------------------------------
/arduinov1.2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/arduinov1.2.zip
--------------------------------------------------------------------------------
/arduinov1.3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/arduinov1.3.zip
--------------------------------------------------------------------------------
/doc/README.md:
--------------------------------------------------------------------------------
1 | A versatile Arduino stationary dcc decoder
2 | ==========================================
3 |
4 | test
5 |
6 | 
7 |
8 | When constructing my dcc based train model, I looked for dcc decoder to pilot light (SMD 0402, or standard led), but had difficulty to program them for custom scenario (blinking, road works style, …). There are also some DIY dcc decoder (opendcc decoder) but didn’t manage to make them working. So I decided to create my own stationary dcc decoder based on Arduino, to be able to reprogram it at wish.
9 |
10 | This decoder is pretty simple, you can
11 | * assign it a dcc address (via a learning switch button)
12 | * connect LED lights, or a relay
13 | * choose the light mode if you connected lights. There are 3 different modes you can choose via a push button: constant light (on or off), flicker mode, or 3 way road work lights mode
14 |
15 | It has been designed to be powered by a 16V AC, but can be as well be powered via DCC signal (15v or 18v), or a DC signal.
16 |
17 | Using it
18 | ========
19 |
20 | 
21 |
22 | Powering
23 | --------
24 | This decoder is designed to be powered by a 16V AC power source. It is possible to power it with the dcc signal, but my circuit is not the most power efficient stationary decoder (due to the fact that it power lights, an arduino and eventually a relay), so you don’t want that, except in rare situation.
25 |
26 | This is why there are 2 set of cables:
27 | * one for the 16V AC
28 | * one for the DCC signal
29 |
30 | Assign a dcc address
31 | --------------------
32 |
33 | To assign a dcc address, you have to use the learning switch opposite to the Arduino.
34 | In that position, each time it see a stationary decoder command coming on, it will store it as its new address (and will acknowledge that by blinking the status led).
35 | So to assign a dcc address you just have to
36 | * push the learning switch opposite to the Arduino.
37 | * send a command with the wished address
38 | * you will see the status led blinking, stating that it saw the address and learned it
39 | * push back the learning switch towards the Arduino
40 |
41 |
42 | Connect light
43 | -------------
44 |
45 | On the bottom of the card, you have 3 slots for leds. The + of the led must be on the left. Normaly you can connect only one led per slot (due to the nominal tension that each led has, 2 different led don't have the exact same nominal tension).
46 |
47 | If you use the push button, you will circle between 3 modes:
48 | * constantly on (or off)
49 | * flickering seldomly
50 | * 3 way road work lights (it will switch on the first light, then the second light, then the 3rd light, and cycle again to the first light)
51 |
52 | You just has to use the push button to cycle between the 3 modes. The little status led, will tell you in which mode you are.
53 |
54 |
55 | Connect relay
56 | -------------
57 |
58 | TBD
59 |
60 | Connect to the other IO
61 | =======================
62 |
63 | 
64 |
65 | There are some generic IO available, that expose
66 | * 5v and ground
67 | * analog pins 6 and 7
68 | * and digital pins 6 and 7
69 |
70 | You can use them at your own advantage, but you will need to reprogram the Arduino to you own purpose: I didn’t program anything on them.
71 |
72 | Assemble it
73 | ===========
74 |
75 | If you don’t want to assemble, or just want the PCB already fabricated, contact me, and I can provide it for you: nicolas.zin@gmail.com
76 |
77 | If you prefer to fully assemble it, you will need to get the PCB, and of course the components.
78 | The PCB gerber files are here: [arduinov1.3.zip](arduinov1.3.zip) (for the eagle source check below)
79 |
80 | To fully assemble it, the full Bill Of Material is:
81 |
82 |
83 | item |how many |ref
84 | ------------------------|---------|------------------------------------
85 | arduino nano |1 |aliexpress
86 | bridge rectifier |1 |mouser 625-B40C800G-E4
87 | capa 330uF |1 |mouser 667-EEU-FM1C331
88 | capa 10uF |1 |mouser 581-TAP106K025SCS
89 | voltage regulator 7807TV|1 |mouser 511-L7809CV
90 | R 50 ohm |1 |mouser 71-CPF150R000FEE14
91 | relay |1 |sparkfun COM-00100
92 | diode 4004 |1 |mouser 512-1N4004
93 | transistor 2n2222 |1 |mouser 610-2N2222
94 | R 10k ohm |5 |mouser 71-CCF50-10K
95 | R 1k ohm |1 |mouser 603-CFR-12JR-521K
96 | diode 4148 |1 |mouser 512-1N4148
97 | toggle button |1 |sparkfun COM-00102
98 | push button |1 |SPARKUN COM-00097
99 | led |1 |mouser 941-C4SMFRJSCT0W0BB2
100 | R 400 ohm |3 |mouser 660-MF1/2LCT52R391J
101 | terminal block 2 pos |8 |mouser 845-30.702
102 | terminal block 3 pos |1 |mouser 845-30.703
103 | headers |2 |mouser 855-M20-7821546
104 | high speed optocoupler |1 |mouser 630-6N137
105 |
106 |
107 | 
108 |
109 | Reprogram it
110 | ============
111 |
112 | If you are familiar with Arduino programming, you can re-program it to whatever needs you have. That the beauty of it. Here are the arduino sources: [dccduino.ino](arduinoSource/dccduino.ino)
113 |
114 | It is based on the dcc decoder library from Minabay: https://github.com/MynaBay/DCC_Decoder (included in the arduinoSource/dccduino directory)
115 |
116 |
117 | Extend it
118 | =========
119 |
120 | If you want to develop your own dcc decoder, I provide you the eagle source: [arduinoDcc1.3.sch](arduinoDcc1.3.sch) and [arduinoDcc1.3.brd](arduinoDcc1.3.brd)
121 |
122 | Feel free to adapt it to your needs, but I provide it as is, i.e. I can answer some question but if you decide to change the layout, you are on your own
123 |
124 | 
125 |
126 | Licence
127 | =======
128 | The Arduino code and the Eagle schema are under the [GPL v2](gpl-2.0.txt)
129 |
--------------------------------------------------------------------------------
/doc/arduinodcc.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/arduinodcc.JPG
--------------------------------------------------------------------------------
/doc/arduinodcc.xcf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/arduinodcc.xcf
--------------------------------------------------------------------------------
/doc/arduinodccExplanation.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/arduinodccExplanation.JPG
--------------------------------------------------------------------------------
/doc/arduinodccExplanation2.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/arduinodccExplanation2.JPG
--------------------------------------------------------------------------------
/doc/schemaEagle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/schemaEagle.png
--------------------------------------------------------------------------------
/doc/schemaEagle2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/doc/schemaEagle2.png
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 | # the i18n builder cannot share the environment and doctrees with the others
15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
16 |
17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
18 |
19 | help:
20 | @echo "Please use \`make ' where is one of"
21 | @echo " html to make standalone HTML files"
22 | @echo " dirhtml to make HTML files named index.html in directories"
23 | @echo " singlehtml to make a single large HTML file"
24 | @echo " pickle to make pickle files"
25 | @echo " json to make JSON files"
26 | @echo " htmlhelp to make HTML files and a HTML help project"
27 | @echo " qthelp to make HTML files and a qthelp project"
28 | @echo " devhelp to make HTML files and a Devhelp project"
29 | @echo " epub to make an epub"
30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
31 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
32 | @echo " text to make text files"
33 | @echo " man to make manual pages"
34 | @echo " texinfo to make Texinfo files"
35 | @echo " info to make Texinfo files and run them through makeinfo"
36 | @echo " gettext to make PO message catalogs"
37 | @echo " changes to make an overview of all changed/added/deprecated items"
38 | @echo " linkcheck to check all external links for integrity"
39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40 |
41 | clean:
42 | -rm -rf $(BUILDDIR)/*
43 |
44 | html:
45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48 |
49 | dirhtml:
50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51 | @echo
52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53 |
54 | singlehtml:
55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56 | @echo
57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58 |
59 | pickle:
60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61 | @echo
62 | @echo "Build finished; now you can process the pickle files."
63 |
64 | json:
65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66 | @echo
67 | @echo "Build finished; now you can process the JSON files."
68 |
69 | htmlhelp:
70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71 | @echo
72 | @echo "Build finished; now you can run HTML Help Workshop with the" \
73 | ".hhp project file in $(BUILDDIR)/htmlhelp."
74 |
75 | qthelp:
76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77 | @echo
78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/markdown-guide.qhcp"
81 | @echo "To view the help file:"
82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/markdown-guide.qhc"
83 |
84 | devhelp:
85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86 | @echo
87 | @echo "Build finished."
88 | @echo "To view the help file:"
89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/markdown-guide"
90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/markdown-guide"
91 | @echo "# devhelp"
92 |
93 | epub:
94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95 | @echo
96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97 |
98 | latex:
99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100 | @echo
101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
103 | "(use \`make latexpdf' here to do that automatically)."
104 |
105 | latexpdf:
106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107 | @echo "Running LaTeX files through pdflatex..."
108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110 |
111 | text:
112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113 | @echo
114 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
115 |
116 | man:
117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118 | @echo
119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120 |
121 | texinfo:
122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
123 | @echo
124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
125 | @echo "Run \`make' in that directory to run these through makeinfo" \
126 | "(use \`make info' here to do that automatically)."
127 |
128 | info:
129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
130 | @echo "Running Texinfo files through makeinfo..."
131 | make -C $(BUILDDIR)/texinfo info
132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
133 |
134 | gettext:
135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
136 | @echo
137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
138 |
139 | changes:
140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
141 | @echo
142 | @echo "The overview file is in $(BUILDDIR)/changes."
143 |
144 | linkcheck:
145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
146 | @echo
147 | @echo "Link check complete; look for any errors in the above output " \
148 | "or in $(BUILDDIR)/linkcheck/output.txt."
149 |
150 | doctest:
151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
152 | @echo "Testing of doctests in the sources finished, look at the " \
153 | "results in $(BUILDDIR)/doctest/output.txt."
154 |
--------------------------------------------------------------------------------
/docs/arduinodcc.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/docs/arduinodcc.JPG
--------------------------------------------------------------------------------
/docs/arduinodccExplanation.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/docs/arduinodccExplanation.JPG
--------------------------------------------------------------------------------
/docs/arduinodccExplanation2.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/docs/arduinodccExplanation2.JPG
--------------------------------------------------------------------------------
/docs/basics.rst:
--------------------------------------------------------------------------------
1 | ================
2 | Markdown Basics
3 | ================
4 |
5 | This should cover 99% of your Markdown needs.
6 |
7 | Blockquotes
8 | ============
9 |
10 | To enclose a segment of text in blockquotes, one must prefix each written line
11 | with a greater-than sign.
12 |
13 | Markdown::
14 |
15 | > ## Blockquoted header
16 | >
17 | > This is blockquoted text.
18 | >
19 | > This is a second paragraph within the blockquoted text.
20 |
21 | Output:
22 |
23 | .. code-block:: html
24 |
25 |
26 |
Blockquoted header
27 |
28 |
This is blockquoted text.
29 |
30 |
This is a second paragraph within the blockquoted text.
31 |
32 |
33 |
34 | Code: Block
35 | =============
36 |
37 | To specify an entire block of pre-formatted code, indent every line of the block by 1 tab or 4 spaces. Ampersands and angle brackets will automatically be translated into HTML entities.
38 |
39 | Markdown::
40 |
41 | If you want to mark something as code, indent it by 4 spaces.
42 |
43 |
This has been indented 4 spaces.
44 |
45 | .. code-block:: html
46 |
47 |
If you want to mark something as code, indent it by 4 spaces.
48 |
49 | <p>This has been indented 4 spaces.</p>
50 |
51 | Code: Inline
52 | ===============
53 |
54 | Inline code descriptions can be done via the use of the backtick quotes. Any ampersands and angle brackets will automatically be translated into HTML entities.
55 |
56 | Markdown::
57 |
58 | Markdown is a `text-to-html` conversion tool for writers.
59 |
60 | Output:
61 |
62 | .. code-block:: html
63 |
64 |
Markdown is a `<em>text-to-html</em>` conversion tool for writers.
65 |
66 |
67 | Emphasis: Italics
68 | ==================
69 |
70 | To emphasize text wrap it with either a asterisk or underscore.
71 |
72 | Markdown::
73 |
74 | This is *emphasized* _text_.
75 |
76 | Output:
77 |
78 | .. code-block:: html
79 |
80 |
This is emphasizedtext.
81 |
82 | Emphasis: Strong
83 | ================
84 |
85 | To boldly emphasize text, wrap it with either double asterisks or double underscores.
86 |
87 | Markdown::
88 |
89 | This is very heavily **emphasized** __text__.
90 |
91 | Output:
92 |
93 | .. code-block:: html
94 |
95 |
This is very heavily emphasizedtext.
96 |
97 |
98 | Headers
99 | ========
100 |
101 | HTML headings are produced by placing a number of hashes before the header
102 | text corresponding to the level of heading desired (HTML offers six levels of
103 | headings).
104 |
105 | Markdown::
106 |
107 | # First-level heading
108 |
109 | #### Fourth-level heading
110 |
111 | Output:
112 |
113 | .. code-block:: html
114 |
115 |
First-level heading
116 |
117 |
Fourth-level heading
118 |
119 |
120 | Horizontal rules
121 | =================
122 |
123 | You can create a horizontal rule (````) by placing 3 or more phens, asterisks, or underscores on a single line. You can also place spaces between them.
124 |
125 | Markdown::
126 |
127 | * * *
128 |
129 | ***
130 |
131 | *****
132 |
133 | - - -
134 |
135 | ---------------------------------------
136 |
137 | Output:
138 |
139 | .. code-block:: html
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | Images: Inline
152 | ===============
153 |
154 | Image syntax is very similar to Link syntax, but prefixed with an exclamation point.
155 |
156 | Markdown::
157 |
158 | 
159 |
160 | Output:
161 |
162 | .. code-block:: html
163 |
164 |
165 |
166 | Line Return
167 | ============
168 |
169 | To force a line return, place two empty spaces at the end of a line.
170 |
171 | Markdown::
172 |
173 | Forcing a line-break\s\s
174 | Next line in the list
175 |
176 | Output:
177 |
178 | .. code-block:: html
179 |
180 | Forcing a line-break
181 | Next line in the list
182 |
183 | Links: Inline
184 | ===============
185 |
186 | Inline-style links use parentheses immediately after the link text.
187 |
188 | Markdown::
189 |
190 | This is an [example link](http://example.com/).
191 |
192 | Output:
193 |
194 | .. code-block:: html
195 |
196 |
228 |
229 | Lists: Simple
230 | =============
231 |
232 | Creating simple links is done by using plus, hyphens or asterisks as list markers. These list markers are interchangeable.
233 |
234 | Markdown::
235 |
236 | + One
237 | - Two
238 | * Three
239 |
240 | Output:
241 |
242 | .. code-block:: html
243 |
244 |
245 |
One
246 |
Two
247 |
Three
248 |
249 |
250 | Lists: Nested
251 | =============
252 |
253 | Nest a list requires you to indent by **exactly** four spaces.
254 |
255 | Markdown::
256 |
257 | + One
258 | + Two
259 | + Three
260 | - Nested One
261 | - Nested Two
262 |
263 | Output:
264 |
265 | .. code-block:: html
266 |
267 |
268 |
One
269 |
Two
270 |
Three
271 |
272 |
Nested One
273 |
Nested Two
274 |
275 |
276 |
277 |
278 |
279 | Paragraphs
280 | ===========
281 |
282 | A paragraph is one or more consecutive lines of text separated by one or more
283 | blank lines. Normal paragraphs should not be indented with spaces or tabs.
284 |
285 | Markdown::
286 |
287 | This is a paragraph. It has two sentences.
288 |
289 | This is another paragraph. It also has two sentences.
290 |
291 | Output:
292 |
293 | .. code-block:: html
294 |
295 |
This is a paragraph. It has two sentences.
296 |
297 |
This is another paragraph. It also has two sentences.
298 |
299 | ----
300 |
301 |
302 | Images: Reference
303 | =================
304 |
305 | TODO
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # markdown-guide documentation build configuration file, created by
4 | # sphinx-quickstart on Wed Aug 15 10:20:33 2012.
5 | #
6 | # This file is execfile()d with the current directory set to its containing dir.
7 | #
8 | # Note that not all possible configuration values are present in this
9 | # autogenerated file.
10 | #
11 | # All configuration values have a default; values that are commented out
12 | # serve to show the default.
13 |
14 | import sys, os
15 |
16 | # If extensions (or modules to document with autodoc) are in another directory,
17 | # add these directories to sys.path here. If the directory is relative to the
18 | # documentation root, use os.path.abspath to make it absolute, like shown here.
19 | #sys.path.insert(0, os.path.abspath('.'))
20 |
21 | # -- General configuration -----------------------------------------------------
22 |
23 | # If your documentation needs a minimal Sphinx version, state it here.
24 | #needs_sphinx = '1.0'
25 |
26 | # Add any Sphinx extension module names here, as strings. They can be extensions
27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28 | extensions = []
29 |
30 | # Add any paths that contain templates here, relative to this directory.
31 | templates_path = ['_templates']
32 |
33 | # The suffix of source filenames.
34 | source_suffix = '.rst'
35 |
36 | # The encoding of source files.
37 | #source_encoding = 'utf-8-sig'
38 |
39 | # The master toctree document.
40 | master_doc = 'index'
41 |
42 | # General information about the project.
43 | project = u'markdown-guide'
44 | copyright = u'2012, Daniel Greenfeld'
45 |
46 | # The version info for the project you're documenting, acts as replacement for
47 | # |version| and |release|, also used in various other places throughout the
48 | # built documents.
49 | #
50 | # The short X.Y version.
51 | version = '0.1'
52 | # The full version, including alpha/beta/rc tags.
53 | release = '0.1'
54 |
55 | # The language for content autogenerated by Sphinx. Refer to documentation
56 | # for a list of supported languages.
57 | #language = None
58 |
59 | # There are two options for replacing |today|: either, you set today to some
60 | # non-false value, then it is used:
61 | #today = ''
62 | # Else, today_fmt is used as the format for a strftime call.
63 | #today_fmt = '%B %d, %Y'
64 |
65 | # List of patterns, relative to source directory, that match files and
66 | # directories to ignore when looking for source files.
67 | exclude_patterns = ['_build']
68 |
69 | # The reST default role (used for this markup: `text`) to use for all documents.
70 | #default_role = None
71 |
72 | # If true, '()' will be appended to :func: etc. cross-reference text.
73 | #add_function_parentheses = True
74 |
75 | # If true, the current module name will be prepended to all description
76 | # unit titles (such as .. function::).
77 | #add_module_names = True
78 |
79 | # If true, sectionauthor and moduleauthor directives will be shown in the
80 | # output. They are ignored by default.
81 | #show_authors = False
82 |
83 | # The name of the Pygments (syntax highlighting) style to use.
84 | pygments_style = 'sphinx'
85 |
86 | # A list of ignored prefixes for module index sorting.
87 | #modindex_common_prefix = []
88 |
89 |
90 | # -- Options for HTML output ---------------------------------------------------
91 |
92 | # The theme to use for HTML and HTML Help pages. See the documentation for
93 | # a list of builtin themes.
94 | html_theme = 'default'
95 |
96 | # Theme options are theme-specific and customize the look and feel of a theme
97 | # further. For a list of options available for each theme, see the
98 | # documentation.
99 | #html_theme_options = {}
100 |
101 | # Add any paths that contain custom themes here, relative to this directory.
102 | #html_theme_path = []
103 |
104 | # The name for this set of Sphinx documents. If None, it defaults to
105 | # " v documentation".
106 | #html_title = None
107 |
108 | # A shorter title for the navigation bar. Default is the same as html_title.
109 | #html_short_title = None
110 |
111 | # The name of an image file (relative to this directory) to place at the top
112 | # of the sidebar.
113 | #html_logo = None
114 |
115 | # The name of an image file (within the static path) to use as favicon of the
116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
117 | # pixels large.
118 | #html_favicon = None
119 |
120 | # Add any paths that contain custom static files (such as style sheets) here,
121 | # relative to this directory. They are copied after the builtin static files,
122 | # so a file named "default.css" will overwrite the builtin "default.css".
123 | html_static_path = ['_static']
124 |
125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
126 | # using the given strftime format.
127 | #html_last_updated_fmt = '%b %d, %Y'
128 |
129 | # If true, SmartyPants will be used to convert quotes and dashes to
130 | # typographically correct entities.
131 | #html_use_smartypants = True
132 |
133 | # Custom sidebar templates, maps document names to template names.
134 | #html_sidebars = {}
135 |
136 | # Additional templates that should be rendered to pages, maps page names to
137 | # template names.
138 | #html_additional_pages = {}
139 |
140 | # If false, no module index is generated.
141 | #html_domain_indices = True
142 |
143 | # If false, no index is generated.
144 | #html_use_index = True
145 |
146 | # If true, the index is split into individual pages for each letter.
147 | #html_split_index = False
148 |
149 | # If true, links to the reST sources are added to the pages.
150 | #html_show_sourcelink = True
151 |
152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
153 | #html_show_sphinx = True
154 |
155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
156 | #html_show_copyright = True
157 |
158 | # If true, an OpenSearch description file will be output, and all pages will
159 | # contain a tag referring to it. The value of this option must be the
160 | # base URL from which the finished HTML is served.
161 | #html_use_opensearch = ''
162 |
163 | # This is the file name suffix for HTML files (e.g. ".xhtml").
164 | #html_file_suffix = None
165 |
166 | # Output file base name for HTML help builder.
167 | htmlhelp_basename = 'markdown-guidedoc'
168 |
169 |
170 | # -- Options for LaTeX output --------------------------------------------------
171 |
172 | latex_elements = {
173 | # The paper size ('letterpaper' or 'a4paper').
174 | #'papersize': 'letterpaper',
175 |
176 | # The font size ('10pt', '11pt' or '12pt').
177 | #'pointsize': '10pt',
178 |
179 | # Additional stuff for the LaTeX preamble.
180 | #'preamble': '',
181 | }
182 |
183 | # Grouping the document tree into LaTeX files. List of tuples
184 | # (source start file, target name, title, author, documentclass [howto/manual]).
185 | latex_documents = [
186 | ('index', 'markdown-guide.tex', u'markdown-guide Documentation',
187 | u'Daniel Greenfeld', 'manual'),
188 | ]
189 |
190 | # The name of an image file (relative to this directory) to place at the top of
191 | # the title page.
192 | #latex_logo = None
193 |
194 | # For "manual" documents, if this is true, then toplevel headings are parts,
195 | # not chapters.
196 | #latex_use_parts = False
197 |
198 | # If true, show page references after internal links.
199 | #latex_show_pagerefs = False
200 |
201 | # If true, show URL addresses after external links.
202 | #latex_show_urls = False
203 |
204 | # Documents to append as an appendix to all manuals.
205 | #latex_appendices = []
206 |
207 | # If false, no module index is generated.
208 | #latex_domain_indices = True
209 |
210 |
211 | # -- Options for manual page output --------------------------------------------
212 |
213 | # One entry per manual page. List of tuples
214 | # (source start file, name, description, authors, manual section).
215 | man_pages = [
216 | ('index', 'markdown-guide', u'markdown-guide Documentation',
217 | [u'Daniel Greenfeld'], 1)
218 | ]
219 |
220 | # If true, show URL addresses after external links.
221 | #man_show_urls = False
222 |
223 |
224 | # -- Options for Texinfo output ------------------------------------------------
225 |
226 | # Grouping the document tree into Texinfo files. List of tuples
227 | # (source start file, target name, title, author,
228 | # dir menu entry, description, category)
229 | texinfo_documents = [
230 | ('index', 'markdown-guide', u'markdown-guide Documentation',
231 | u'Daniel Greenfeld', 'markdown-guide', 'One line description of project.',
232 | 'Miscellaneous'),
233 | ]
234 |
235 | # Documents to append as an appendix to all manuals.
236 | #texinfo_appendices = []
237 |
238 | # If false, no module index is generated.
239 | #texinfo_domain_indices = True
240 |
241 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
242 | #texinfo_show_urls = 'footnote'
243 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | Github project
2 | ==============
3 | You can find the whole project source on github: [https://github.com/nzin/arduinodcc](https://github.com/nzin/arduinodcc)
4 |
5 | A versatile Arduino stationary dcc decoder
6 | ==========================================
7 |
8 | 
9 |
10 | When constructing my dcc based train model, I looked for dcc decoder to pilot light (SMD 0402, or standard led), but had difficulty to program them for custom scenario (blinking, road works style, …). There are also some DIY dcc decoder (opendcc decoder) but didn’t manage to make them working. So I decided to create my own stationary dcc decoder based on Arduino (nano), to be able to reprogram it at wish.
11 |
12 | This decoder is pretty simple, you can
13 |
14 | - assign it a dcc address (via a learning switch button)
15 | - connect LED lights, or a relay
16 | - choose the light mode if you connected lights. There are 3 different modes you can choose via a push button: constant light (on or off), flicker mode, or 3 way road work lights mode
17 |
18 | It has been designed to be powered by a 16V AC, but can be as well be powered via DCC signal (15v or 18v), or a DC signal.
19 |
20 | Using it
21 | ========
22 |
23 | 
24 |
25 | Powering
26 | --------
27 | This decoder is designed to be powered by a 16V AC power source. It is possible to power it with the dcc signal, but my circuit is not the most power efficient stationary decoder (due to the fact that it power lights, an arduino and eventually a relay), so you don’t want that, except in rare situation.
28 |
29 | This is why there are 2 set of cables:
30 |
31 | - one for the 16V AC
32 | - one for the DCC signal
33 |
34 | Assign a dcc address
35 | --------------------
36 |
37 | To assign a dcc address, you have to use the learning switch opposite to the Arduino.
38 | In that position, each time it see a stationary decoder command coming on, it will store it as its new address (and will acknowledge that by blinking the status led).
39 | So to assign a dcc address you just have to
40 |
41 | - push the learning switch opposite to the Arduino.
42 | - send a command with the wished address
43 | - you will see the status led blinking, stating that it saw the address and learned it
44 | - push back the learning switch towards the Arduino
45 |
46 |
47 | Connect light
48 | -------------
49 |
50 | On the bottom of the card, you have 3 slots for leds. The + of the led must be on the left. Normaly you can connect only one led per slot (due to the nominal tension that each led has, 2 different led don't have the exact same nominal tension).
51 |
52 | If you use the push button, you will circle between 3 modes:
53 |
54 | - constantly on (or off)
55 | - flickering seldomly
56 | - 3 way road work lights (it will switch on the first light, then the second light, then the 3rd light, and cycle again to the first light)
57 |
58 | You just has to use the push button to cycle between the 3 modes. The little status led, will tell you in which mode you are.
59 |
60 |
61 | Connect relay
62 | -------------
63 |
64 | Close to the lights there is a block of 3 pins for the relay (if you decide to build it), which are in this order: low ouput, input, high output.
65 | So the one on the middle is your input (whatever your input is), and the relay will connect it either to the left pin or to the right pin.
66 |
67 | Connect to the other IO
68 | =======================
69 |
70 | 
71 |
72 | There are some generic IO available, that expose
73 |
74 | - 5v and ground
75 | - analog pins 6 and 7
76 | - and digital pins 6 and 7
77 |
78 | You can use them at your own advantage, but you will need to reprogram the Arduino to you own purpose: I didn’t program anything on them.
79 |
80 | Assemble it
81 | ===========
82 |
83 | If you don’t want to assemble, or just want the PCB already fabricated, contact me, and I can provide it for you: nicolas.zin@gmail.com
84 |
85 | If you prefer to fully assemble it, you will need to get the PCB, and of course the components.
86 | The PCB gerber files are here: [arduinov1.3.zip](https://github.com/nzin/arduinodcc/raw/master/arduinov1.3.zip) (for the eagle source check below)
87 |
88 | To fully assemble it, the full Bill Of Material is:
89 |
90 |
91 | item |how many |ref
92 | ------------------------|---------|------------------------------------
93 | arduino nano |1 |aliexpress
94 | bridge rectifier |1 |mouser 625-B40C800G-E4 (or 625-B380C800G-E4)
95 | capa 330uF |1 |mouser 667-EEU-FM1C331
96 | capa 10uF |1 |mouser 581-TAP106K025SCS
97 | DC-DC converter (9VDC) |1 |mouser 490-V7809-1000 (or cheaper: voltage regulator mouser 511-L7809CV but buy also a heatsink!!)
98 | R 50 ohm |1 |mouser 71-CPF150R000FEE14
99 | relay |1 |sparkfun COM-00100
100 | diode 4004 |1 |mouser 512-1N4004 (or 625-1N4004-E3/54)
101 | transistor 2n2222 |1 |mouser 610-2N2222
102 | R 10k ohm |5 |mouser 71-CCF50-10K
103 | R 1k ohm |1 |mouser 603-CFR-12JR-521K
104 | diode 4148 |1 |mouser 512-1N4148
105 | toggle button |1 |sparkfun COM-00102 (maybe mouser 633-SS12SDP2)
106 | push button |1 |SPARKUN COM-00097 (ou mouser 693-1301.9308)
107 | led |1 |mouser 941-C4SMFRJSCT0W0BB2 (or mouser 630-HLMP-1301)
108 | terminal block 2 pos |8 |mouser 651-1729128
109 | terminal block 3 pos |1 |mouser 651-1729131
110 | headers |2 |mouser 855-M20-7821546
111 | high speed optocoupler |1 |mouser 630-6N137-000E
112 | R 200 ohm |4 |mouser 71-CCF50-200
113 | shottky diode |1 |mouser 833-SR108-TP
114 |
115 |
116 | 
117 |
118 | Reprogram it
119 | ============
120 |
121 | If you are familiar with Arduino programming, you can re-program it to whatever needs you have. That the beauty of it. Here are the arduino sources: [dccduino.ino](https://github.com/nzin/arduinodcc/blob/master/arduinoSource/dccduino)
122 |
123 | It is based on the dcc decoder library from Minabay: https://github.com/MynaBay/DCC_Decoder (included in the arduinoSource/dccduino directory)
124 |
125 |
126 | Extend it
127 | =========
128 |
129 | If you want to develop your own dcc decoder, I provide you the eagle source: [arduinoDcc1.3.sch](https://github.com/nzin/arduinodcc/raw/master/arduinoDcc1.3.sch) and [arduinoDcc1.3.brd](https://github.com/nzin/arduinodcc/raw/master/arduinoDcc1.3.brd)
130 |
131 | Feel free to adapt it to your needs, but I provide it as is, i.e. I can answer some question but if you decide to change the layout, you are on your own
132 |
133 | 
134 |
135 | Licence
136 | =======
137 | The Arduino code and the Eagle schema are under the [GPL v2](https://github.com/nzin/arduinodcc/blob/master/gpl-2.0.txt)
138 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. markdown-guide documentation master file, created by
2 | sphinx-quickstart on Wed Aug 15 10:20:33 2012.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to markdown-guide's documentation!
7 | ==========================================
8 |
9 | .. pull-quote::
10 |
11 | Markdown is a lightweight markup language, originally created by John Gruber and Aaron Swartz allowing
12 | people "to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally
13 | valid XHTML (or HTML).
14 |
15 | Source: http://en.wikipedia.org/wiki/Markdown
16 |
17 | This is a syntax guide designed to provide very clear, understandable examples of Markdown usage. It borrows from several
18 | sources including:
19 |
20 | * http://en.wikipedia.org/wiki/Markdown
21 | * http://daringfireball.net/projects/markdown/
22 |
23 | Contents:
24 |
25 | .. toctree::
26 | :maxdepth: 2
27 |
28 | basics
29 |
30 |
31 | Indices and tables
32 | ==================
33 |
34 | * :ref:`genindex`
35 | * :ref:`modindex`
36 | * :ref:`search`
37 |
38 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | set I18NSPHINXOPTS=%SPHINXOPTS% .
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. linkcheck to check all external links for integrity
37 | echo. doctest to run all doctests embedded in the documentation if enabled
38 | goto end
39 | )
40 |
41 | if "%1" == "clean" (
42 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
43 | del /q /s %BUILDDIR%\*
44 | goto end
45 | )
46 |
47 | if "%1" == "html" (
48 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
49 | if errorlevel 1 exit /b 1
50 | echo.
51 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
52 | goto end
53 | )
54 |
55 | if "%1" == "dirhtml" (
56 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
57 | if errorlevel 1 exit /b 1
58 | echo.
59 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
60 | goto end
61 | )
62 |
63 | if "%1" == "singlehtml" (
64 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
65 | if errorlevel 1 exit /b 1
66 | echo.
67 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
68 | goto end
69 | )
70 |
71 | if "%1" == "pickle" (
72 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
73 | if errorlevel 1 exit /b 1
74 | echo.
75 | echo.Build finished; now you can process the pickle files.
76 | goto end
77 | )
78 |
79 | if "%1" == "json" (
80 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
81 | if errorlevel 1 exit /b 1
82 | echo.
83 | echo.Build finished; now you can process the JSON files.
84 | goto end
85 | )
86 |
87 | if "%1" == "htmlhelp" (
88 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
89 | if errorlevel 1 exit /b 1
90 | echo.
91 | echo.Build finished; now you can run HTML Help Workshop with the ^
92 | .hhp project file in %BUILDDIR%/htmlhelp.
93 | goto end
94 | )
95 |
96 | if "%1" == "qthelp" (
97 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
98 | if errorlevel 1 exit /b 1
99 | echo.
100 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
101 | .qhcp project file in %BUILDDIR%/qthelp, like this:
102 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\markdown-guide.qhcp
103 | echo.To view the help file:
104 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\markdown-guide.ghc
105 | goto end
106 | )
107 |
108 | if "%1" == "devhelp" (
109 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
110 | if errorlevel 1 exit /b 1
111 | echo.
112 | echo.Build finished.
113 | goto end
114 | )
115 |
116 | if "%1" == "epub" (
117 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
118 | if errorlevel 1 exit /b 1
119 | echo.
120 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
121 | goto end
122 | )
123 |
124 | if "%1" == "latex" (
125 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
129 | goto end
130 | )
131 |
132 | if "%1" == "text" (
133 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
134 | if errorlevel 1 exit /b 1
135 | echo.
136 | echo.Build finished. The text files are in %BUILDDIR%/text.
137 | goto end
138 | )
139 |
140 | if "%1" == "man" (
141 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
142 | if errorlevel 1 exit /b 1
143 | echo.
144 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
145 | goto end
146 | )
147 |
148 | if "%1" == "texinfo" (
149 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
150 | if errorlevel 1 exit /b 1
151 | echo.
152 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
153 | goto end
154 | )
155 |
156 | if "%1" == "gettext" (
157 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
158 | if errorlevel 1 exit /b 1
159 | echo.
160 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
161 | goto end
162 | )
163 |
164 | if "%1" == "changes" (
165 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
166 | if errorlevel 1 exit /b 1
167 | echo.
168 | echo.The overview file is in %BUILDDIR%/changes.
169 | goto end
170 | )
171 |
172 | if "%1" == "linkcheck" (
173 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
174 | if errorlevel 1 exit /b 1
175 | echo.
176 | echo.Link check complete; look for any errors in the above output ^
177 | or in %BUILDDIR%/linkcheck/output.txt.
178 | goto end
179 | )
180 |
181 | if "%1" == "doctest" (
182 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
183 | if errorlevel 1 exit /b 1
184 | echo.
185 | echo.Testing of doctests in the sources finished, look at the ^
186 | results in %BUILDDIR%/doctest/output.txt.
187 | goto end
188 | )
189 |
190 | :end
191 |
--------------------------------------------------------------------------------
/docs/schemaEagle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/docs/schemaEagle.png
--------------------------------------------------------------------------------
/docs/schemaEagle2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nzin/arduinodcc/cf1c27303ab94856d5b93d22b930092144a3eb54/docs/schemaEagle2.png
--------------------------------------------------------------------------------
/gpl-2.0.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 |
294 | Copyright (C)
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | , 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------