source: rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 7.7 KB
Line 
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 clink 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 */
38int analogInputsToReport = 0; // bitwise array to store pin reporting
39int analogPin = 0; // counter for reading analog pins
40
41/* digital pins */
42byte reportPINs[TOTAL_PORTS]; // PIN == input port
43byte previousPINs[TOTAL_PORTS]; // PIN == input port
44byte pinStatus[TOTAL_PINS]; // store pin status, default OUTPUT
45byte portStatus[TOTAL_PORTS];
46
47/* timer variables */
48unsigned long currentMillis; // store the current value from millis()
49unsigned long previousMillis; // for comparison with currentMillis
50
51
52/*==============================================================================
53 * FUNCTIONS
54 *============================================================================*/
55
56void 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() */
69void 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 */
87void 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
123void analogWriteCallback(byte pin, int value)
124{
125 setPinModeCallback(pin, PIN_MODE_PWM);
126 analogWrite(pin, value);
127}
128
129void 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//}
150void 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
161void 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 *============================================================================*/
171void 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 *============================================================================*/
215void 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}
Note: See TracBrowser for help on using the repository browser.