]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
2c63c2ab765577b1c9ed2501acbc57b90bebe5ad
[Cipher_code.git] / Arduino / libraries / Firmata / examples / OldStandardFirmata / OldStandardFirmata.ino
1 /*
2  * Firmata is a generic protocol for communicating with microcontrollers
3  * from software on a host computer. It is intended to work with
4  * any host computer software package.
5  *
6  * To download a host software package, please click on the following link
7  * to open the download page in your default browser.
8  *
9  * http://firmata.org/wiki/Download
10  */
11
12 /*
13   Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
14
15   This library is free software; you can redistribute it and/or
16   modify it under the terms of the GNU Lesser General Public
17   License as published by the Free Software Foundation; either
18   version 2.1 of the License, or (at your option) any later version.
19
20   See file LICENSE.txt for further informations on licensing terms.
21  */
22
23 /*
24  * This is an old version of StandardFirmata (v2.0).  It is kept here because
25  * its the last version that works on an ATMEGA8 chip.  Also, it can be used
26  * for host software that has not been updated to a newer version of the
27  * protocol.  It also uses the old baud rate of 115200 rather than 57600.
28  */
29
30 #include <EEPROM.h>
31 #include <Firmata.h>
32
33 /*==============================================================================
34  * GLOBAL VARIABLES
35  *============================================================================*/
36
37 /* analog inputs */
38 int analogInputsToReport = 0; // bitwise array to store pin reporting
39 int analogPin = 0; // counter for reading analog pins
40
41 /* digital pins */
42 byte reportPINs[TOTAL_PORTS];   // PIN == input port
43 byte previousPINs[TOTAL_PORTS]; // PIN == input port
44 byte pinStatus[TOTAL_PINS]; // store pin status, default OUTPUT
45 byte portStatus[TOTAL_PORTS];
46
47 /* timer variables */
48 unsigned long currentMillis;     // store the current value from millis()
49 unsigned long previousMillis;    // for comparison with currentMillis
50
51
52 /*==============================================================================
53  * FUNCTIONS
54  *============================================================================*/
55
56 void outputPort(byte portNumber, byte portValue)
57 {
58   portValue = portValue & ~ portStatus[portNumber];
59   if (previousPINs[portNumber] != portValue) {
60     Firmata.sendDigitalPort(portNumber, portValue);
61     previousPINs[portNumber] = portValue;
62     Firmata.sendDigitalPort(portNumber, portValue);
63   }
64 }
65
66 /* -----------------------------------------------------------------------------
67  * check all the active digital inputs for change of state, then add any events
68  * to the Serial output queue using Serial.print() */
69 void checkDigitalInputs(void)
70 {
71   byte i, tmp;
72   for (i = 0; i < TOTAL_PORTS; i++) {
73     if (reportPINs[i]) {
74       switch (i) {
75         case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/1
76         case 1: outputPort(1, PINB); break;
77         case 2: outputPort(2, PINC); break;
78       }
79     }
80   }
81 }
82
83 // -----------------------------------------------------------------------------
84 /* sets the pin mode to the correct state and sets the relevant bits in the
85  * two bit-arrays that track Digital I/O and PWM status
86  */
87 void setPinModeCallback(byte pin, int mode) {
88   byte port = 0;
89   byte offset = 0;
90
91   if (pin < 8) {
92     port = 0;
93     offset = 0;
94   } else if (pin < 14) {
95     port = 1;
96     offset = 8;
97   } else if (pin < 22) {
98     port = 2;
99     offset = 14;
100   }
101
102   if (pin > 1) { // ignore RxTx (pins 0 and 1)
103     pinStatus[pin] = mode;
104     switch (mode) {
105       case INPUT:
106         pinMode(pin, INPUT);
107         portStatus[port] = portStatus[port] & ~ (1 << (pin - offset));
108         break;
109       case OUTPUT:
110         digitalWrite(pin, LOW); // disable PWM
111       case PWM:
112         pinMode(pin, OUTPUT);
113         portStatus[port] = portStatus[port] | (1 << (pin - offset));
114         break;
115       //case ANALOG: // TODO figure this out
116       default:
117         Firmata.sendString("");
118     }
119     // TODO: save status to EEPROM here, if changed
120   }
121 }
122
123 void analogWriteCallback(byte pin, int value)
124 {
125   setPinModeCallback(pin, PIN_MODE_PWM);
126   analogWrite(pin, value);
127 }
128
129 void digitalWriteCallback(byte port, int value)
130 {
131   switch (port) {
132     case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1)
133       // 0xFF03 == B1111111100000011    0x03 == B00000011
134       PORTD = (value & ~ 0xFF03) | (PORTD & 0x03);
135       break;
136     case 1: // pins 8-13 (14,15 are disabled for the crystal)
137       PORTB = (byte)value;
138       break;
139     case 2: // analog pins used as digital
140       PORTC = (byte)value;
141       break;
142   }
143 }
144
145 // -----------------------------------------------------------------------------
146 /* sets bits in a bit array (int) to toggle the reporting of the analogIns
147  */
148 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
149 //}
150 void reportAnalogCallback(byte pin, int value)
151 {
152   if (value == 0) {
153     analogInputsToReport = analogInputsToReport & ~ (1 << pin);
154   }
155   else { // everything but 0 enables reporting of that pin
156     analogInputsToReport = analogInputsToReport | (1 << pin);
157   }
158   // TODO: save status to EEPROM here, if changed
159 }
160
161 void reportDigitalCallback(byte port, int value)
162 {
163   reportPINs[port] = (byte)value;
164   if (port == 2) // turn off analog reporting when used as digital
165     analogInputsToReport = 0;
166 }
167
168 /*==============================================================================
169  * SETUP()
170  *============================================================================*/
171 void setup()
172 {
173   byte i;
174
175   Firmata.setFirmwareVersion(2, 0);
176
177   Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
178   Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
179   Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
180   Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
181   Firmata.attach(SET_PIN_MODE, setPinModeCallback);
182
183   portStatus[0] = B00000011;  // ignore Tx/RX pins
184   portStatus[1] = B11000000;  // ignore 14/15 pins
185   portStatus[2] = B00000000;
186
187   //    for(i=0; i<TOTAL_PINS; ++i) { // TODO make this work with analogs
188   for (i = 0; i < 14; ++i) {
189     setPinModeCallback(i, OUTPUT);
190   }
191   // set all outputs to 0 to make sure internal pull-up resistors are off
192   PORTB = 0; // pins 8-15
193   PORTC = 0; // analog port
194   PORTD = 0; // pins 0-7
195
196   // TODO rethink the init, perhaps it should report analog on default
197   for (i = 0; i < TOTAL_PORTS; ++i) {
198     reportPINs[i] = false;
199   }
200   // TODO: load state from EEPROM here
201
202   /* send digital inputs here, if enabled, to set the initial state on the
203    * host computer, since once in the loop(), this firmware will only send
204    * digital data on change. */
205   if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1
206   if (reportPINs[1]) outputPort(1, PINB);
207   if (reportPINs[2]) outputPort(2, PINC);
208
209   Firmata.begin(115200);
210 }
211
212 /*==============================================================================
213  * LOOP()
214  *============================================================================*/
215 void loop()
216 {
217   /* DIGITALREAD - as fast as possible, check for changes and output them to the
218    * FTDI buffer using Serial.print()  */
219   checkDigitalInputs();
220   currentMillis = millis();
221   if (currentMillis - previousMillis > 20) {
222     previousMillis += 20;     // run this every 20ms
223     /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
224      * all serialReads at once, i.e. empty the buffer */
225     while (Firmata.available())
226       Firmata.processInput();
227     /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
228      * 60 bytes. use a timer to sending an event character every 4 ms to
229      * trigger the buffer to dump. */
230
231     /* ANALOGREAD - right after the event character, do all of the
232      * analogReads().  These only need to be done every 4ms. */
233     for (analogPin = 0; analogPin < TOTAL_ANALOG_PINS; analogPin++) {
234       if ( analogInputsToReport & (1 << analogPin) ) {
235         Firmata.sendAnalog(analogPin, analogRead(analogPin));
236       }
237     }
238   }
239 }