Changeset 224 for rtos_arduino/trunk/arduino_lib/libraries
- Timestamp:
- Apr 30, 2016, 11:29:25 PM (8 years ago)
- Location:
- rtos_arduino/trunk/arduino_lib/libraries
- Files:
-
- 46 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
rtos_arduino/trunk/arduino_lib/libraries/Ciao/examples/CiaoRestClient/CiaoRestClient.ino
r175 r224 3 3 4 4 #define CONNECTOR "rest" 5 #define SERVER_ADDR "192.168. 0.100" // change ip address with your server ip address5 #define SERVER_ADDR "192.168.1.1" // change ip address with your server ip address 6 6 7 int buttonState = LOW; //this variable tracks the state of the button, low if not pressed, high if pressed8 int ledState = -1; //this variable tracks the state of the LED, negative if off, positive if on7 int buttonState; //this variable tracks the state of the button, low if not pressed, high if pressed 8 int ledState = HIGH; //this variable tracks the state of the LED, negative if off, positive if on 9 9 long lastDebounceTime = 0; // the last time the output pin was toggled 10 10 long debounceDelay = 50; // the debounce time; increase if the output flickers 11 String command = "/arduino/mode/13/output"; 12 int previous_value = LOW; 11 13 12 14 void setup() { 13 15 Ciao.begin(); 16 Ciao.write(CONNECTOR, SERVER_ADDR, command); 14 17 pinMode(2, INPUT); 15 18 … … 20 23 //sample the state of the button - is it pressed or not? 21 24 buttonState = digitalRead(2); 22 25 23 26 //filter out any noise by setting a time buffer 24 if ( (millis() - lastDebounceTime) > debounceDelay) { 25 26 //if the button has been pressed, lets toggle the LED from "off to on" or "on to off" 27 if ( (buttonState == HIGH) && (ledState < 0) ) { 28 29 CiaoData data = Ciao.write(CONNECTOR, SERVER_ADDR, "/arduino/digital/12/1"); //turn LED on 30 ledState = -ledState; //now the LED is on, we need to change the state 31 lastDebounceTime = millis(); //set the current time 27 if ( (buttonState == HIGH) && (previous_value == LOW) && (millis() - lastDebounceTime) > debounceDelay ) { 28 if (ledState == HIGH){ 29 command = "/arduino/digital/13/0"; 30 ledState = LOW; 32 31 } 33 else if ( (buttonState == HIGH) && (ledState > 0) ) { 34 35 CiaoData data = Ciao.write(CONNECTOR, SERVER_ADDR, "/arduino/digital/12/0"); //turn LED off 36 ledState = -ledState; //now the LED is off, we need to change the state 37 lastDebounceTime = millis(); //set the current time 38 39 if (!data.isEmpty()){ 40 Ciao.println( "State: " + String (data.get(1)) ); 41 Ciao.println( "Response: " + String (data.get(2)) ); 42 } 43 else{ 44 Ciao.println ("Write Error"); 45 } 46 32 else{ 33 command = "/arduino/digital/13/1"; 34 ledState = HIGH; 47 35 } 48 36 37 lastDebounceTime = millis(); //set the current time 38 CiaoData data = Ciao.write(CONNECTOR, SERVER_ADDR, command); 39 if (!data.isEmpty()){ 40 Ciao.println( "State: " + String (data.get(1)) ); 41 Ciao.println( "Response: " + String (data.get(2)) ); 42 } 43 else{ 44 Ciao.println ("Write Error"); 45 } 46 49 47 } 50 48 49 previous_value = buttonState; 50 51 51 } -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/examples/CiaoRestServer/CiaoRestServer.ino
r175 r224 1 1 /* 2 2 3 This sketch uses the xmpp connector to receive command for the MCU from a xmpp client. 3 This sketch uses the restserver connector receive rest calls. It allows access to 4 the analog and digital pin of the board via rest calls. 5 6 supported boards: Yun,Tian. 4 7 5 8 Possible commands to send from the xmpp client: 6 9 7 * "digital/PIN" -> to read a digital PIN 8 * "digital/PIN/VALUE" -> to write a digital PIN (VALUE: 1/0) 9 * "analog/PIN/VALUE" -> to write in a PWM PIN(VALUE range: 0 - 255); 10 * "analog/PIN" -> to read a analog PIN 11 * "servo/PIN/VALUE" -> to write angle in a SERVO PIN(VALUE range: 0 - 180); 12 * "mode/PIN/VALUE" -> to set the PIN mode (VALUE: input / output) 13 * "ledon" -> turn on led 13 14 * "ledoff" -> turn off led 13 15 * "ciao" -> random answers in 5 different languages 16 17 NOTE: be sure to activate and configure xmpp connector on Linino OS 18 http://labs.arduino.org/Ciao 19 10 * "/arduino/digital/PIN" -> to read a digital PIN 11 * "/arduino/digital/PIN/VALUE" -> to write a digital PIN (VALUE: 1/0) 12 * "/arduino/analog/PIN/VALUE" -> to write in a PWM PIN(VALUE range: 0 - 255); 13 * "/arduino/analog/PIN" -> to read a analog PIN 14 * "/arduino/servo/PIN/VALUE" -> to write angle in a SERVO PIN(VALUE range: 0 - 180); 15 * "/arduino/mode/PIN/VALUE" -> to set the PIN mode (VALUE: input / output) 16 17 Example: 18 "/arduino/mode/13/output" -> pinMode(13, OUTPUT) 19 "/arduino/digital/13/1" -> digitalWrite(13, HIGH) 20 21 22 NOTE: be sure to activate and configure restserver connector on Linino OS 23 http://labs.arduino.org/Ciao 24 20 25 created September 2015 21 26 by andrea[at]arduino[dot]org 22 27 23 28 */ 24 29 25 30 #include <Ciao.h> 26 31 #include <Servo.h> … … 35 40 void loop() { 36 41 37 CiaoData data = Ciao.read("restserver"); 38 if(!data.isEmpty()){ 42 CiaoData data = Ciao.read("restserver"); 43 if(!data.isEmpty()){ 39 44 String id = data.get(0); 40 45 String sender = data.get(1); 41 46 String message = data.get(2); 42 47 43 48 message.toUpperCase(); 44 49 45 50 String command[3]; 46 51 47 52 splitString(message,"/",command,3); 48 53 execute(command,id); … … 71 76 void servoCommand(String cmd[], String id){ 72 77 int pin, value; 73 78 74 79 pin = (cmd[1]).toInt(); 75 80 76 81 if (cmd[2] != "-1") { 77 82 value = (cmd[2]).toInt(); … … 85 90 } 86 91 else 87 Ciao.writeResponse("restserver",id,"Invalid command"); 92 Ciao.writeResponse("restserver",id,"Invalid command"); 88 93 } 89 94 90 95 void digitalCommand(String cmd[], String id) { 91 96 int pin, value; 92 97 93 98 pin = (cmd[1]).toInt(); 94 99 95 100 if (cmd[2] != "-1") { 96 101 value = (cmd[2]).toInt(); … … 99 104 Ciao.writeResponse("restserver",id,"Pin D"+String(pin)+" ON"); 100 105 else if(value == 0) 101 Ciao.writeResponse("restserver",id,"Pin D"+String(pin)+" OFF"); 106 Ciao.writeResponse("restserver",id,"Pin D"+String(pin)+" OFF"); 102 107 } 103 108 else if (cmd[2] == "-1") { … … 111 116 112 117 pin = (cmd[1]).toInt(); 113 118 114 119 if (cmd[2] != "-1") { 115 120 value =(cmd[2]).toInt(); … … 127 132 128 133 pin = (cmd[1]).toInt(); 129 134 130 135 if (cmd[2] == "INPUT") { 131 136 pinMode(pin, INPUT); -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/keywords.txt
r175 r224 7 7 ####################################### 8 8 9 Ciao 10 CiaoData 11 Wifi 12 WifiData 9 Ciao KEYWORD3 10 CiaoData KEYWORD3 11 Wifi KEYWORD3 12 WifiData KEYWORD3 13 13 14 14 ####################################### … … 16 16 ####################################### 17 17 18 begin KEYWORD2 19 writeResponse KEYWORD2 20 available KEYWORD2 21 read KEYWORD2 22 write KEYWORD2 23 bool KEYWORD2 18 writeResponse KEYWORD2 19 available KEYWORD2 20 read KEYWORD2 21 write KEYWORD2 24 22 23 ####################################### 24 # Constants (LITERAL1) 25 ####################################### -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/library.properties
r175 r224 1 1 name=Ciao 2 version= 1.02 version=0.0.3 3 3 author=Arduino srl 4 4 maintainer=Arduino srl<info@arduino.org> -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/Ciao.h
r175 r224 30 30 31 31 #include <Arduino.h> 32 #include <Stream.h> 32 33 #include "lib/CiaoData.h" 33 34 #if defined(__AVR_ATmega328P__) 34 #include "lib/rest.h"35 35 #include "lib/SC16IS750.h" 36 #include "lib/espduino.h"37 #else38 #include <Stream.h>39 36 #endif 40 37 … … 44 41 #define BAUDRATE 250000 45 42 #elif defined(ARDUINO_ARCH_SAMD) 46 #define BAUDRATE 11520043 #define BAUDRATE 4000000 47 44 #endif 48 45 … … 55 52 CiaoData parse( String, String); 56 53 void println(String log){}; 57 #if defined(__AVR_ATmega32U4__)58 54 CiaoClass(Stream &_stream); 59 #elif defined(ARDUINO_ARCH_SAMD)60 CiaoClass(Serial_ stream);61 #endif62 55 63 56 private: 64 57 void dropAll(); 65 58 bool started; 66 #if defined(__AVR_ATmega32U4__)67 59 Stream &stream; 68 #elif defined(ARDUINO_ARCH_SAMD)69 Serial_ stream;70 #endif71 60 }; 72 61 … … 80 69 } 81 70 #elif defined(ARDUINO_ARCH_SAMD) 82 SerialCiaoClass(Serial_ serial)83 : CiaoClass( serial){84 // Empty 71 SerialCiaoClass(Serial_ &_serial) 72 : CiaoClass(_serial), serial(_serial) { 73 // Empty 85 74 } 86 75 #endif … … 93 82 HardwareSerial &serial; 94 83 #elif defined(ARDUINO_ARCH_SAMD) 95 Serial_ serial;84 Serial_ &serial; 96 85 #endif 97 86 }; … … 103 92 #else 104 93 105 // class CiaoData { 106 // public: 107 108 // char* get(int index){ 109 // return msg_split[index]; 110 // } 111 112 // public: 113 // char* msg_split[3]; 114 115 // }; 94 class ArduinoWifiClass : public WifiData 95 { 116 96 117 class CiaoClass { 97 public: 98 void begin(); 99 100 boolean connected(); 101 void connect(char* , char*); 102 103 void powerON(); 104 void powerOFF(); 105 106 107 }; 108 109 class CiaoClass : public WifiData 110 { 118 111 public: 119 112 void begin(); … … 124 117 CiaoData write( char*, char*, String ); // ârestâ, âhostnameâ, âStringoneâ, 125 118 CiaoData write( char*, char*, String, char*); // ârestâ, âhostnameâ, âStringoneâ, âmethodâ 126 127 void print(String str);128 void println(String str);129 119 130 120 }; 121 122 131 123 extern CiaoClass Ciao; 124 extern ArduinoWifiClass Wifi; 132 125 133 126 #endif -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/lib/Ciao.cpp
r175 r224 24 24 */ 25 25 26 #include "Ciao.h"27 26 28 27 #if defined(__AVR_ATmega32U4__) || defined(ARDUINO_ARCH_SAMD) 29 28 30 #if defined(__AVR_ATmega32U4__) 29 #include "Ciao.h" 30 31 31 CiaoClass::CiaoClass(Stream &_stream) : 32 32 stream(_stream), started(false) { 33 33 // Empty 34 34 } 35 #elif defined(ARDUINO_ARCH_SAMD)36 CiaoClass::CiaoClass(Serial_ stream){37 // Empty38 }39 #endif40 35 41 36 void CiaoClass::begin() { … … 60 55 } 61 56 do{ 62 #if defined(__AVR_ATmega32U4__)63 57 stream.print(F("run-ciao\n")); //start bridge python 64 58 stream.readStringUntil(END_TX_CHAR); 65 #endif66 59 delay(3000); 67 60 stream.println("ciao;r;status"); //check if bridge python is running -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/lib/SC16IS750.cpp
r175 r224 27 27 #define WIRE Wire 28 28 29 30 WifiData::WifiData(uint8_t prtcl, uint8_t addr_sspin) 31 { 32 protocol = prtcl; 33 if ( protocol == SC16IS750_PROTOCOL_I2C ) { 34 device_address_sspin = (addr_sspin>>1); 35 } else { 36 device_address_sspin = addr_sspin; 37 } 29 WifiData::WifiData() 30 { 31 device_address_sspin = (SC16IS750_ADDRESS_AA >> 1); 38 32 peek_flag = 0; 39 33 } … … 41 35 void WifiData::begin(uint32_t baud) 42 36 { 43 //Serial.println("1111111111111111"); 37 44 38 if ( protocol == SC16IS750_PROTOCOL_I2C) { 45 //Serial.println("22222222222222");46 39 WIRE.begin(); 47 40 } -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/lib/SC16IS750.h
r175 r224 104 104 #define SC16IS750_PROTOCOL_I2C (0) 105 105 #define SC16IS750_PROTOCOL_I2C (0) 106 #define END "<!--~-->" 106 #define DELIMITER "<!--~-->" 107 #define EOL '\0' 107 108 108 109 class WifiData : public Stream 109 110 { 110 111 public: 111 WifiData(uint8_t prtcl = SC16IS750_PROTOCOL_I2C, uint8_t addr = SC16IS750_ADDRESS_AD);112 WifiData(); 112 113 void begin(uint32_t baud); 113 114 int read(); -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/lib/espduino.cpp
r175 r224 188 188 } 189 189 190 ESP::ESP(Stream *serial , int chip_pd):191 _serial(serial) , _chip_pd(chip_pd)190 ESP::ESP(Stream *serial): 191 _serial(serial) 192 192 { 193 193 _debugEn = false; … … 195 195 } 196 196 197 ESP::ESP(Stream *serial, Stream* debug, int chip_pd): 198 _serial(serial), _debug(debug), _chip_pd(chip_pd) 199 { 200 _debugEn = true; 201 //_serial = _debug; 202 init(); 203 } 197 204 198 void ESP::enable() 205 199 { -
rtos_arduino/trunk/arduino_lib/libraries/Ciao/src/lib/espduino.h
r175 r224 92 92 { 93 93 public: 94 ESP(Stream *serial, Stream* debug, int chip_pd);95 ESP(Stream *serial , int chip_pd);94 //ESP(Stream *serial, Stream* debug, int chip_pd); 95 ESP(Stream *serial); //ok 96 96 Stream *_debug; 97 97 -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AllInputsFirmata/AllInputsFirmata.ino
r136 r224 23 23 int previousAnalogValues[TOTAL_ANALOG_PINS]; 24 24 25 byte portStatus[TOTAL_PORTS]; 25 byte portStatus[TOTAL_PORTS]; // each bit: 1=pin is digital input, 0=other/ignore 26 26 byte previousPINs[TOTAL_PORTS]; 27 27 … … 46 46 byte i, port, status; 47 47 48 Firmata.setFirmwareVersion( 0, 1);48 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 49 49 50 50 for (pin = 0; pin < TOTAL_PINS; pin++) { -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/AnalogFirmata/AnalogFirmata.ino
r136 r224 54 54 { 55 55 if (value == 0) { 56 analogInputsToReport = analogInputsToReport & ~ (1 << pin);56 analogInputsToReport = analogInputsToReport & ~ (1 << pin); 57 57 } 58 58 else { // everything but 0 enables reporting of that pin … … 67 67 void setup() 68 68 { 69 Firmata.setFirmwareVersion( 0, 2);69 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 70 70 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 71 71 Firmata.attach(REPORT_ANALOG, reportAnalogCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/EchoString/EchoString.ino
r136 r224 22 22 23 23 24 void sysexCallback(byte command, byte argc, byte *argv)24 void sysexCallback(byte command, byte argc, byte *argv) 25 25 { 26 26 Firmata.sendSysex(command, argc, argv); … … 29 29 void setup() 30 30 { 31 Firmata.setFirmwareVersion( 0, 1);31 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 32 32 Firmata.attach(STRING_DATA, stringCallback); 33 33 Firmata.attach(START_SYSEX, sysexCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/OldStandardFirmata/OldStandardFirmata.ino
r136 r224 56 56 void outputPort(byte portNumber, byte portValue) 57 57 { 58 portValue = portValue & ~ portStatus[portNumber];58 portValue = portValue & ~ portStatus[portNumber]; 59 59 if (previousPINs[portNumber] != portValue) { 60 60 Firmata.sendDigitalPort(portNumber, portValue); … … 73 73 if (reportPINs[i]) { 74 74 switch (i) { 75 case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/175 case 0: outputPort(0, PIND & ~ B00000011); break; // ignore Rx/Tx 0/1 76 76 case 1: outputPort(1, PINB); break; 77 77 case 2: outputPort(2, PINC); break; … … 105 105 case INPUT: 106 106 pinMode(pin, INPUT); 107 portStatus[port] = portStatus[port] & ~ (1 << (pin - offset));107 portStatus[port] = portStatus[port] & ~ (1 << (pin - offset)); 108 108 break; 109 109 case OUTPUT: … … 113 113 portStatus[port] = portStatus[port] | (1 << (pin - offset)); 114 114 break; 115 115 //case ANALOG: // TODO figure this out 116 116 default: 117 117 Firmata.sendString(""); … … 123 123 void analogWriteCallback(byte pin, int value) 124 124 { 125 setPinModeCallback(pin, P WM);125 setPinModeCallback(pin, PIN_MODE_PWM); 126 126 analogWrite(pin, value); 127 127 } … … 132 132 case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1) 133 133 // 0xFF03 == B1111111100000011 0x03 == B00000011 134 PORTD = (value & ~ 0xFF03) | (PORTD & 0x03);134 PORTD = (value & ~ 0xFF03) | (PORTD & 0x03); 135 135 break; 136 136 case 1: // pins 8-13 (14,15 are disabled for the crystal) … … 151 151 { 152 152 if (value == 0) { 153 analogInputsToReport = analogInputsToReport & ~ (1 << pin);153 analogInputsToReport = analogInputsToReport & ~ (1 << pin); 154 154 } 155 155 else { // everything but 0 enables reporting of that pin … … 203 203 * host computer, since once in the loop(), this firmware will only send 204 204 * digital data on change. */ 205 if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1205 if (reportPINs[0]) outputPort(0, PIND & ~ B00000011); // ignore Rx/Tx 0/1 206 206 if (reportPINs[1]) outputPort(1, PINB); 207 207 if (reportPINs[2]) outputPort(2, PINC); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/ServoFirmata/ServoFirmata.ino
r136 r224 13 13 * included in Arduino 0017 14 14 * 15 * TODO add message to configure minPulse/maxPulse/degrees16 *17 15 * This example code is in the public domain. 18 16 */ … … 22 20 23 21 Servo servos[MAX_SERVOS]; 22 byte servoPinMap[TOTAL_PINS]; 23 byte servoCount = 0; 24 24 25 25 void analogWriteCallback(byte pin, int value) 26 26 { 27 if (IS_PIN_ SERVO(pin)) {28 servos[ PIN_TO_SERVO(pin)].write(value);27 if (IS_PIN_DIGITAL(pin)) { 28 servos[servoPinMap[pin]].write(value); 29 29 } 30 } 31 32 void systemResetCallback() 33 { 34 servoCount = 0; 30 35 } 31 36 … … 34 39 byte pin; 35 40 36 Firmata.setFirmwareVersion( 0, 2);41 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 37 42 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 43 Firmata.attach(SYSTEM_RESET, systemResetCallback); 38 44 45 Firmata.begin(57600); 46 systemResetCallback(); 47 48 // attach servos from first digital pin up to max number of 49 // servos supported for the board 39 50 for (pin = 0; pin < TOTAL_PINS; pin++) { 40 if (IS_PIN_SERVO(pin)) { 41 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 51 if (IS_PIN_DIGITAL(pin)) { 52 if (servoCount < MAX_SERVOS) { 53 servoPinMap[pin] = servoCount; 54 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin)); 55 servoCount++; 56 } 42 57 } 43 58 } 44 45 Firmata.begin(57600);46 59 } 47 60 … … 51 64 Firmata.processInput(); 52 65 } 53 -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleAnalogFirmata/SimpleAnalogFirmata.ino
r136 r224 28 28 void setup() 29 29 { 30 Firmata.setFirmwareVersion( 0, 1);30 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 31 31 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); 32 32 Firmata.begin(57600); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/SimpleDigitalFirmata/SimpleDigitalFirmata.ino
r136 r224 53 53 void setup() 54 54 { 55 Firmata.setFirmwareVersion( 0, 1);55 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 56 56 Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); 57 57 Firmata.attach(SET_PIN_MODE, setPinModeCallback); -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/examples/StandardFirmata/StandardFirmata.ino
r136 r224 1 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 /* 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 list of Firmata client libraries your default browser. 8 9 https://github.com/firmata/arduino#firmata-client-libraries 10 13 11 Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. 14 12 Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. 15 13 Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. 16 Copyright (C) 2009-201 1Jeff Hoefs. All rights reserved.14 Copyright (C) 2009-2016 Jeff Hoefs. All rights reserved. 17 15 18 16 This library is free software; you can redistribute it and/or … … 23 21 See file LICENSE.txt for further informations on licensing terms. 24 22 25 formatted using the GNU C formatting and indenting23 Last updated by Jeff Hoefs: January 10th, 2016 26 24 */ 27 28 /*29 * TODO: use Program Control to load stored profiles from EEPROM30 */31 25 32 26 #include <Servo.h> … … 34 28 #include <Firmata.h> 35 29 36 // move the following defines to Firmata.h? 37 #define I2C_WRITE B00000000 38 #define I2C_READ B00001000 39 #define I2C_READ_CONTINUOUSLY B00010000 40 #define I2C_STOP_READING B00011000 41 #define I2C_READ_WRITE_MODE_MASK B00011000 30 #define I2C_WRITE B00000000 31 #define I2C_READ B00001000 32 #define I2C_READ_CONTINUOUSLY B00010000 33 #define I2C_STOP_READING B00011000 34 #define I2C_READ_WRITE_MODE_MASK B00011000 42 35 #define I2C_10BIT_ADDRESS_MODE_MASK B00100000 43 44 #define MAX_QUERIES 8 45 #define MINIMUM_SAMPLING_INTERVAL 10 46 47 #define REGISTER_NOT_SPECIFIED -1 36 #define I2C_END_TX_MASK B01000000 37 #define I2C_STOP_TX 1 38 #define I2C_RESTART_TX 0 39 #define I2C_MAX_QUERIES 8 40 #define I2C_REGISTER_NOT_SPECIFIED -1 41 42 // the minimum interval for sampling analog input 43 #define MINIMUM_SAMPLING_INTERVAL 1 44 48 45 49 46 /*============================================================================== … … 51 48 *============================================================================*/ 52 49 50 #ifdef FIRMATA_SERIAL_FEATURE 51 SerialFirmata serialFeature; 52 #endif 53 53 54 /* analog inputs */ 54 55 int analogInputsToReport = 0; // bitwise array to store pin reporting … … 59 60 60 61 /* pins configuration */ 61 byte pinConfig[TOTAL_PINS]; // configuration of every pin62 62 byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else 63 int pinState[TOTAL_PINS]; // any value that has been written64 63 65 64 /* timer variables */ 66 65 unsigned long currentMillis; // store the current value from millis() 67 66 unsigned long previousMillis; // for comparison with currentMillis 68 int samplingInterval = 19;// how often to run the main loop (in ms)67 unsigned int samplingInterval = 19; // how often to run the main loop (in ms) 69 68 70 69 /* i2c data */ 71 70 struct i2c_device_info { 72 71 byte addr; 73 bytereg;72 int reg; 74 73 byte bytes; 74 byte stopTX; 75 75 }; 76 76 77 77 /* for i2c read continuous more */ 78 i2c_device_info query[ MAX_QUERIES];79 80 byte i2cRxData[ 32];78 i2c_device_info query[I2C_MAX_QUERIES]; 79 80 byte i2cRxData[64]; 81 81 boolean isI2CEnabled = false; 82 82 signed char queryIndex = -1; 83 unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom() 83 // default delay time between i2c read request and Wire.requestFrom() 84 unsigned int i2cReadDelayTime = 0; 84 85 85 86 Servo servos[MAX_SERVOS]; 87 byte servoPinMap[TOTAL_PINS]; 88 byte detachedServos[MAX_SERVOS]; 89 byte detachedServoCount = 0; 90 byte servoCount = 0; 91 92 boolean isResetting = false; 93 94 95 /* utility functions */ 96 void wireWrite(byte data) 97 { 98 #if ARDUINO >= 100 99 Wire.write((byte)data); 100 #else 101 Wire.send(data); 102 #endif 103 } 104 105 byte wireRead(void) 106 { 107 #if ARDUINO >= 100 108 return Wire.read(); 109 #else 110 return Wire.receive(); 111 #endif 112 } 113 86 114 /*============================================================================== 87 115 * FUNCTIONS 88 116 *============================================================================*/ 89 117 90 void readAndReportData(byte address, int theRegister, byte numBytes) { 118 void attachServo(byte pin, int minPulse, int maxPulse) 119 { 120 if (servoCount < MAX_SERVOS) { 121 // reuse indexes of detached servos until all have been reallocated 122 if (detachedServoCount > 0) { 123 servoPinMap[pin] = detachedServos[detachedServoCount - 1]; 124 if (detachedServoCount > 0) detachedServoCount--; 125 } else { 126 servoPinMap[pin] = servoCount; 127 servoCount++; 128 } 129 if (minPulse > 0 && maxPulse > 0) { 130 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); 131 } else { 132 servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin)); 133 } 134 } else { 135 Firmata.sendString("Max servos attached"); 136 } 137 } 138 139 void detachServo(byte pin) 140 { 141 servos[servoPinMap[pin]].detach(); 142 // if we're detaching the last servo, decrement the count 143 // otherwise store the index of the detached servo 144 if (servoPinMap[pin] == servoCount && servoCount > 0) { 145 servoCount--; 146 } else if (servoCount > 0) { 147 // keep track of detached servos because we want to reuse their indexes 148 // before incrementing the count of attached servos 149 detachedServoCount++; 150 detachedServos[detachedServoCount - 1] = servoPinMap[pin]; 151 } 152 153 servoPinMap[pin] = 255; 154 } 155 156 void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) { 91 157 // allow I2C requests that don't require a register read 92 158 // for example, some devices using an interrupt pin to signify new data available 93 159 // do not always require the register read so upon interrupt you call Wire.requestFrom() 94 if (theRegister != REGISTER_NOT_SPECIFIED) {160 if (theRegister != I2C_REGISTER_NOT_SPECIFIED) { 95 161 Wire.beginTransmission(address); 96 #if ARDUINO >= 100 97 Wire.write((byte)theRegister); 98 #else 99 Wire.send((byte)theRegister); 100 #endif 101 Wire.endTransmission(); 162 wireWrite((byte)theRegister); 163 Wire.endTransmission(stopTX); // default = true 102 164 // do not set a value of 0 103 165 if (i2cReadDelayTime > 0) { … … 112 174 113 175 // check to be sure correct number of bytes were returned by slave 114 if (numBytes == Wire.available()) { 115 i2cRxData[0] = address; 116 i2cRxData[1] = theRegister; 117 for (int i = 0; i < numBytes; i++) { 118 #if ARDUINO >= 100 119 i2cRxData[2 + i] = Wire.read(); 120 #else 121 i2cRxData[2 + i] = Wire.receive(); 122 #endif 123 } 124 } 125 else { 126 if (numBytes > Wire.available()) { 127 Firmata.sendString("I2C Read Error: Too many bytes received"); 128 } else { 129 Firmata.sendString("I2C Read Error: Too few bytes received"); 130 } 176 if (numBytes < Wire.available()) { 177 Firmata.sendString("I2C: Too many bytes received"); 178 } else if (numBytes > Wire.available()) { 179 Firmata.sendString("I2C: Too few bytes received"); 180 } 181 182 i2cRxData[0] = address; 183 i2cRxData[1] = theRegister; 184 185 for (int i = 0; i < numBytes && Wire.available(); i++) { 186 i2cRxData[2 + i] = wireRead(); 131 187 } 132 188 … … 173 229 174 230 // ----------------------------------------------------------------------------- 231 232 /* disable the i2c pins so they can be used for other functions */ 233 void disableI2CPins() { 234 isI2CEnabled = false; 235 // disable read continuous mode for all devices 236 queryIndex = -1; 237 } 238 239 /* sets bits in a bit array (int) to toggle the reporting of the analogIns 240 */ 241 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) { 242 //} 243 void reportAnalogCallback(byte analogPin, int value) 244 { 245 if (analogPin < TOTAL_ANALOG_PINS) { 246 if (value == 0) { 247 analogInputsToReport = analogInputsToReport & ~ (1 << analogPin); 248 } else { 249 analogInputsToReport = analogInputsToReport | (1 << analogPin); 250 // prevent during system reset or all analog pin values will be reported 251 // which may report noise for unconnected analog pins 252 if (!isResetting) { 253 // Send pin value immediately. This is helpful when connected via 254 // ethernet, wi-fi or bluetooth so pin states can be known upon 255 // reconnecting. 256 Firmata.sendAnalog(analogPin, analogRead(analogPin)); 257 } 258 } 259 } 260 // TODO: save status to EEPROM here, if changed 261 } 262 263 // ----------------------------------------------------------------------------- 175 264 /* sets the pin mode to the correct state and sets the relevant bits in the 176 265 * two bit-arrays that track Digital I/O and PWM status … … 178 267 void setPinModeCallback(byte pin, int mode) 179 268 { 180 if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) { 269 if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE) 270 return; 271 272 if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) { 181 273 // disable i2c so pins can be used for other functions 182 274 // the following if statements should reconfigure the pins properly 183 275 disableI2CPins(); 184 276 } 185 if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) { 186 servos[PIN_TO_SERVO(pin)].detach(); 277 if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) { 278 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { 279 detachServo(pin); 280 } 187 281 } 188 282 if (IS_PIN_ANALOG(pin)) { 189 reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting283 reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting 190 284 } 191 285 if (IS_PIN_DIGITAL(pin)) { 192 if (mode == INPUT ) {286 if (mode == INPUT || mode == PIN_MODE_PULLUP) { 193 287 portConfigInputs[pin / 8] |= (1 << (pin & 7)); 194 288 } else { … … 196 290 } 197 291 } 198 pinState[pin] = 0;292 Firmata.setPinState(pin, 0); 199 293 switch (mode) { 200 case ANALOG:294 case PIN_MODE_ANALOG: 201 295 if (IS_PIN_ANALOG(pin)) { 202 296 if (IS_PIN_DIGITAL(pin)) { 203 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 297 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 298 #if ARDUINO <= 100 299 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 204 300 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 205 } 206 pinConfig[pin] = ANALOG; 301 #endif 302 } 303 Firmata.setPinMode(pin, PIN_MODE_ANALOG); 207 304 } 208 305 break; 209 306 case INPUT: 210 307 if (IS_PIN_DIGITAL(pin)) { 211 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 308 pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver 309 #if ARDUINO <= 100 310 // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 212 311 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups 213 pinConfig[pin] = INPUT; 312 #endif 313 Firmata.setPinMode(pin, INPUT); 314 } 315 break; 316 case PIN_MODE_PULLUP: 317 if (IS_PIN_DIGITAL(pin)) { 318 pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP); 319 Firmata.setPinMode(pin, PIN_MODE_PULLUP); 320 Firmata.setPinState(pin, 1); 214 321 } 215 322 break; … … 218 325 digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM 219 326 pinMode(PIN_TO_DIGITAL(pin), OUTPUT); 220 pinConfig[pin] = OUTPUT;221 } 222 break; 223 case P WM:327 Firmata.setPinMode(pin, OUTPUT); 328 } 329 break; 330 case PIN_MODE_PWM: 224 331 if (IS_PIN_PWM(pin)) { 225 332 pinMode(PIN_TO_PWM(pin), OUTPUT); 226 333 analogWrite(PIN_TO_PWM(pin), 0); 227 pinConfig[pin] = PWM; 228 } 229 break; 230 case SERVO: 231 if (IS_PIN_SERVO(pin)) { 232 pinConfig[pin] = SERVO; 233 if (!servos[PIN_TO_SERVO(pin)].attached()) { 234 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin)); 235 } 236 } 237 break; 238 case I2C: 334 Firmata.setPinMode(pin, PIN_MODE_PWM); 335 } 336 break; 337 case PIN_MODE_SERVO: 338 if (IS_PIN_DIGITAL(pin)) { 339 Firmata.setPinMode(pin, PIN_MODE_SERVO); 340 if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) { 341 // pass -1 for min and max pulse values to use default values set 342 // by Servo library 343 attachServo(pin, -1, -1); 344 } 345 } 346 break; 347 case PIN_MODE_I2C: 239 348 if (IS_PIN_I2C(pin)) { 240 349 // mark the pin as i2c 241 350 // the user must call I2C_CONFIG to enable I2C for a device 242 pinConfig[pin] = I2C; 243 } 351 Firmata.setPinMode(pin, PIN_MODE_I2C); 352 } 353 break; 354 case PIN_MODE_SERIAL: 355 #ifdef FIRMATA_SERIAL_FEATURE 356 serialFeature.handlePinMode(pin, PIN_MODE_SERIAL); 357 #endif 244 358 break; 245 359 default: … … 249 363 } 250 364 365 /* 366 * Sets the value of an individual pin. Useful if you want to set a pin value but 367 * are not tracking the digital port state. 368 * Can only be used on pins configured as OUTPUT. 369 * Cannot be used to enable pull-ups on Digital INPUT pins. 370 */ 371 void setPinValueCallback(byte pin, int value) 372 { 373 if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) { 374 if (Firmata.getPinMode(pin) == OUTPUT) { 375 Firmata.setPinState(pin, value); 376 digitalWrite(PIN_TO_DIGITAL(pin), value); 377 } 378 } 379 } 380 251 381 void analogWriteCallback(byte pin, int value) 252 382 { 253 383 if (pin < TOTAL_PINS) { 254 switch ( pinConfig[pin]) {255 case SERVO:256 if (IS_PIN_ SERVO(pin))257 servos[ PIN_TO_SERVO(pin)].write(value);258 pinState[pin] = value;384 switch (Firmata.getPinMode(pin)) { 385 case PIN_MODE_SERVO: 386 if (IS_PIN_DIGITAL(pin)) 387 servos[servoPinMap[pin]].write(value); 388 Firmata.setPinState(pin, value); 259 389 break; 260 case P WM:390 case PIN_MODE_PWM: 261 391 if (IS_PIN_PWM(pin)) 262 392 analogWrite(PIN_TO_PWM(pin), value); 263 pinState[pin] = value;393 Firmata.setPinState(pin, value); 264 394 break; 265 395 } … … 269 399 void digitalWriteCallback(byte port, int value) 270 400 { 271 byte pin, lastPin, mask = 1, pinWriteMask = 0;401 byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0; 272 402 273 403 if (port < TOTAL_PORTS) { … … 278 408 // do not disturb non-digital pins (eg, Rx & Tx) 279 409 if (IS_PIN_DIGITAL(pin)) { 280 // only write to OUTPUT and INPUT (enables pullup)281 410 // do not touch pins in PWM, ANALOG, SERVO or other modes 282 if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) { 283 pinWriteMask |= mask; 284 pinState[pin] = ((byte)value & mask) ? 1 : 0; 411 if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) { 412 pinValue = ((byte)value & mask) ? 1 : 0; 413 if (Firmata.getPinMode(pin) == OUTPUT) { 414 pinWriteMask |= mask; 415 } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) { 416 // only handle INPUT here for backwards compatibility 417 #if ARDUINO > 100 418 pinMode(pin, INPUT_PULLUP); 419 #else 420 // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier 421 pinWriteMask |= mask; 422 #endif 423 } 424 Firmata.setPinState(pin, pinValue); 285 425 } 286 426 } … … 293 433 294 434 // ----------------------------------------------------------------------------- 295 /* sets bits in a bit array (int) to toggle the reporting of the analogIns296 */297 //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {298 //}299 void reportAnalogCallback(byte analogPin, int value)300 {301 if (analogPin < TOTAL_ANALOG_PINS) {302 if (value == 0) {303 analogInputsToReport = analogInputsToReport &~ (1 << analogPin);304 } else {305 analogInputsToReport = analogInputsToReport | (1 << analogPin);306 }307 }308 // TODO: save status to EEPROM here, if changed309 }310 435 311 436 void reportDigitalCallback(byte port, int value) … … 313 438 if (port < TOTAL_PORTS) { 314 439 reportPINs[port] = (byte)value; 440 // Send port value immediately. This is helpful when connected via 441 // ethernet, wi-fi or bluetooth so pin states can be known upon 442 // reconnecting. 443 if (value) outputPort(port, readPort(port, portConfigInputs[port]), true); 315 444 } 316 445 // do not disable analog reporting on these 8 pins, to allow some … … 322 451 } 323 452 453 // ----------------------------------------------------------------------------- 454 455 void enableI2CPins() 456 { 457 byte i; 458 // is there a faster way to do this? would probaby require importing 459 // Arduino.h to get SCL and SDA pins 460 for (i = 0; i < TOTAL_PINS; i++) { 461 if (IS_PIN_I2C(i)) { 462 // mark pins as i2c so they are ignore in non i2c data requests 463 setPinModeCallback(i, PIN_MODE_I2C); 464 } 465 } 466 467 isI2CEnabled = true; 468 469 Wire.begin(); 470 } 471 324 472 /*============================================================================== 325 473 * SYSEX-BASED commands … … 329 477 { 330 478 byte mode; 479 byte stopTX; 331 480 byte slaveAddress; 332 byte slaveRegister;333 481 byte data; 482 int slaveRegister; 334 483 unsigned int delayTime; 335 484 … … 338 487 mode = argv[1] & I2C_READ_WRITE_MODE_MASK; 339 488 if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { 340 Firmata.sendString("10-bit addressing mode is not yet supported");489 Firmata.sendString("10-bit addressing not supported"); 341 490 return; 342 491 } 343 492 else { 344 493 slaveAddress = argv[0]; 494 } 495 496 // need to invert the logic here since 0 will be default for client 497 // libraries that have not updated to add support for restart tx 498 if (argv[1] & I2C_END_TX_MASK) { 499 stopTX = I2C_RESTART_TX; 500 } 501 else { 502 stopTX = I2C_STOP_TX; // default 345 503 } 346 504 … … 350 508 for (byte i = 2; i < argc; i += 2) { 351 509 data = argv[i] + (argv[i + 1] << 7); 352 #if ARDUINO >= 100 353 Wire.write(data); 354 #else 355 Wire.send(data); 356 #endif 510 wireWrite(data); 357 511 } 358 512 Wire.endTransmission(); … … 364 518 slaveRegister = argv[2] + (argv[3] << 7); 365 519 data = argv[4] + (argv[5] << 7); // bytes to read 366 readAndReportData(slaveAddress, (int)slaveRegister, data);367 520 } 368 521 else { 369 522 // a slave register is NOT specified 523 slaveRegister = I2C_REGISTER_NOT_SPECIFIED; 370 524 data = argv[2] + (argv[3] << 7); // bytes to read 371 readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);372 525 } 526 readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX); 373 527 break; 374 528 case I2C_READ_CONTINUOUSLY: 375 if ((queryIndex + 1) >= MAX_QUERIES) {529 if ((queryIndex + 1) >= I2C_MAX_QUERIES) { 376 530 // too many queries, just ignore 377 531 Firmata.sendString("too many queries"); 378 532 break; 379 533 } 534 if (argc == 6) { 535 // a slave register is specified 536 slaveRegister = argv[2] + (argv[3] << 7); 537 data = argv[4] + (argv[5] << 7); // bytes to read 538 } 539 else { 540 // a slave register is NOT specified 541 slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED; 542 data = argv[2] + (argv[3] << 7); // bytes to read 543 } 380 544 queryIndex++; 381 545 query[queryIndex].addr = slaveAddress; 382 query[queryIndex].reg = argv[2] + (argv[3] << 7); 383 query[queryIndex].bytes = argv[4] + (argv[5] << 7); 546 query[queryIndex].reg = slaveRegister; 547 query[queryIndex].bytes = data; 548 query[queryIndex].stopTX = stopTX; 384 549 break; 385 550 case I2C_STOP_READING: … … 390 555 queryIndex = -1; 391 556 } else { 557 queryIndexToSkip = 0; 392 558 // if read continuous mode is enabled for multiple devices, 393 559 // determine which device to stop reading and remove it's data from 394 560 // the array, shifiting other array data to fill the space 395 561 for (byte i = 0; i < queryIndex + 1; i++) { 396 if (query[i].addr = slaveAddress) {562 if (query[i].addr == slaveAddress) { 397 563 queryIndexToSkip = i; 398 564 break; … … 401 567 402 568 for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) { 403 if (i < MAX_QUERIES) {569 if (i < I2C_MAX_QUERIES) { 404 570 query[i].addr = query[i + 1].addr; 405 query[i].reg = query[i + 1]. addr;571 query[i].reg = query[i + 1].reg; 406 572 query[i].bytes = query[i + 1].bytes; 573 query[i].stopTX = query[i + 1].stopTX; 407 574 } 408 575 } … … 433 600 int maxPulse = argv[3] + (argv[4] << 7); 434 601 435 if (IS_PIN_SERVO(pin)) { 436 if (servos[PIN_TO_SERVO(pin)].attached()) 437 servos[PIN_TO_SERVO(pin)].detach(); 438 servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); 439 setPinModeCallback(pin, SERVO); 602 if (IS_PIN_DIGITAL(pin)) { 603 if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { 604 detachServo(pin); 605 } 606 attachServo(pin, minPulse, maxPulse); 607 setPinModeCallback(pin, PIN_MODE_SERVO); 440 608 } 441 609 } … … 466 634 Firmata.write((byte)INPUT); 467 635 Firmata.write(1); 636 Firmata.write((byte)PIN_MODE_PULLUP); 637 Firmata.write(1); 468 638 Firmata.write((byte)OUTPUT); 469 639 Firmata.write(1); 470 640 } 471 641 if (IS_PIN_ANALOG(pin)) { 472 Firmata.write( ANALOG);473 Firmata.write(10); 642 Firmata.write(PIN_MODE_ANALOG); 643 Firmata.write(10); // 10 = 10-bit resolution 474 644 } 475 645 if (IS_PIN_PWM(pin)) { 476 Firmata.write(P WM);477 Firmata.write(8); 478 } 479 if (IS_PIN_ SERVO(pin)) {480 Firmata.write( SERVO);646 Firmata.write(PIN_MODE_PWM); 647 Firmata.write(8); // 8 = 8-bit resolution 648 } 649 if (IS_PIN_DIGITAL(pin)) { 650 Firmata.write(PIN_MODE_SERVO); 481 651 Firmata.write(14); 482 652 } 483 653 if (IS_PIN_I2C(pin)) { 484 Firmata.write(I2C); 485 Firmata.write(1); // to do: determine appropriate value 486 } 654 Firmata.write(PIN_MODE_I2C); 655 Firmata.write(1); // TODO: could assign a number to map to SCL or SDA 656 } 657 #ifdef FIRMATA_SERIAL_FEATURE 658 serialFeature.handleCapability(pin); 659 #endif 487 660 Firmata.write(127); 488 661 } … … 496 669 Firmata.write(pin); 497 670 if (pin < TOTAL_PINS) { 498 Firmata.write( (byte)pinConfig[pin]);499 Firmata.write((byte) pinState[pin]& 0x7F);500 if ( pinState[pin] & 0xFF80) Firmata.write((byte)(pinState[pin]>> 7) & 0x7F);501 if ( pinState[pin] & 0xC000) Firmata.write((byte)(pinState[pin]>> 14) & 0x7F);671 Firmata.write(Firmata.getPinMode(pin)); 672 Firmata.write((byte)Firmata.getPinState(pin) & 0x7F); 673 if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F); 674 if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F); 502 675 } 503 676 Firmata.write(END_SYSEX); … … 512 685 Firmata.write(END_SYSEX); 513 686 break; 514 } 515 } 516 517 void enableI2CPins() 518 { 519 byte i; 520 // is there a faster way to do this? would probaby require importing 521 // Arduino.h to get SCL and SDA pins 522 for (i = 0; i < TOTAL_PINS; i++) { 523 if (IS_PIN_I2C(i)) { 524 // mark pins as i2c so they are ignore in non i2c data requests 525 setPinModeCallback(i, I2C); 526 } 527 } 528 529 isI2CEnabled = true; 530 531 // is there enough time before the first I2C request to call this here? 532 Wire.begin(); 533 } 534 535 /* disable the i2c pins so they can be used for other functions */ 536 void disableI2CPins() { 537 isI2CEnabled = false; 538 // disable read continuous mode for all devices 539 queryIndex = -1; 540 // uncomment the following if or when the end() method is added to Wire library 541 // Wire.end(); 542 } 687 688 case SERIAL_MESSAGE: 689 #ifdef FIRMATA_SERIAL_FEATURE 690 serialFeature.handleSysex(command, argc, argv); 691 #endif 692 break; 693 } 694 } 695 543 696 544 697 /*============================================================================== … … 548 701 void systemResetCallback() 549 702 { 703 isResetting = true; 704 550 705 // initialize a defalt state 551 706 // TODO: option to load config from EEPROM instead of default 707 708 #ifdef FIRMATA_SERIAL_FEATURE 709 serialFeature.reset(); 710 #endif 711 552 712 if (isI2CEnabled) { 553 713 disableI2CPins(); 554 714 } 715 555 716 for (byte i = 0; i < TOTAL_PORTS; i++) { 556 reportPINs[i] = false; 557 portConfigInputs[i] = 0; 717 reportPINs[i] = false; // by default, reporting off 718 portConfigInputs[i] = 0; // until activated 558 719 previousPINs[i] = 0; 559 720 } 560 // pins with analog capability default to analog input 561 // otherwise, pins default to digital output 721 562 722 for (byte i = 0; i < TOTAL_PINS; i++) { 723 // pins with analog capability default to analog input 724 // otherwise, pins default to digital output 563 725 if (IS_PIN_ANALOG(i)) { 564 726 // turns off pullup, configures everything 565 setPinModeCallback(i, ANALOG);566 } else {727 setPinModeCallback(i, PIN_MODE_ANALOG); 728 } else if (IS_PIN_DIGITAL(i)) { 567 729 // sets the output to 0, configures portConfigInputs 568 730 setPinModeCallback(i, OUTPUT); 569 731 } 732 733 servoPinMap[i] = 255; 570 734 } 571 735 // by default, do not report any analog inputs 572 736 analogInputsToReport = 0; 737 738 detachedServoCount = 0; 739 servoCount = 0; 573 740 574 741 /* send digital inputs to set the initial state on the host computer, … … 581 748 } 582 749 */ 750 isResetting = false; 583 751 } 584 752 585 753 void setup() 586 754 { 587 Firmata.setFirmwareVersion(FIRMATA_ MAJOR_VERSION, FIRMATA_MINOR_VERSION);755 Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); 588 756 589 757 Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); … … 592 760 Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); 593 761 Firmata.attach(SET_PIN_MODE, setPinModeCallback); 762 Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback); 594 763 Firmata.attach(START_SYSEX, sysexCallback); 595 764 Firmata.attach(SYSTEM_RESET, systemResetCallback); 596 765 766 // to use a port other than Serial, such as Serial1 on an Arduino Leonardo or Mega, 767 // Call begin(baud) on the alternate serial port and pass it to Firmata to begin like this: 768 // Serial1.begin(57600); 769 // Firmata.begin(Serial1); 770 // However do not do this if you are using SERIAL_MESSAGE 771 597 772 Firmata.begin(57600); 773 while (!Serial) { 774 ; // wait for serial port to connect. Needed for ATmega32u4-based boards and Arduino 101 775 } 776 598 777 systemResetCallback(); // reset to default config 599 778 } … … 610 789 checkDigitalInputs(); 611 790 612 /* S ERIALREAD - processing incoming messagse as soon as possible, while still791 /* STREAMREAD - processing incoming messagse as soon as possible, while still 613 792 * checking digital inputs. */ 614 793 while (Firmata.available()) 615 794 Firmata.processInput(); 616 795 617 /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over 618 * 60 bytes. use a timer to sending an event character every 4 ms to 619 * trigger the buffer to dump. */ 796 // TODO - ensure that Stream buffer doesn't go over 60 bytes 620 797 621 798 currentMillis = millis(); … … 624 801 /* ANALOGREAD - do all analogReads() at the configured sampling interval */ 625 802 for (pin = 0; pin < TOTAL_PINS; pin++) { 626 if (IS_PIN_ANALOG(pin) && pinConfig[pin] ==ANALOG) {803 if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) { 627 804 analogPin = PIN_TO_ANALOG(pin); 628 805 if (analogInputsToReport & (1 << analogPin)) { … … 634 811 if (queryIndex > -1) { 635 812 for (byte i = 0; i < queryIndex + 1; i++) { 636 readAndReportData(query[i].addr, query[i].reg, query[i].bytes); 637 } 638 } 639 } 640 } 813 readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX); 814 } 815 } 816 } 817 818 #ifdef FIRMATA_SERIAL_FEATURE 819 serialFeature.update(); 820 #endif 821 } -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/keywords.txt
r136 r224 7 7 ####################################### 8 8 9 Firmata KEYWORD110 callbackFunction KEYWORD111 systemResetCallbackFunction KEYWORD1 12 stringCallbackFunction KEYWORD113 sysexCallbackFunction KEYWORD19 Firmata KEYWORD1 Firmata 10 callbackFunction KEYWORD1 callbackFunction 11 systemResetCallbackFunction KEYWORD1 systemResetCallbackFunction 12 stringCallbackFunction KEYWORD1 stringCallbackFunction 13 sysexCallbackFunction KEYWORD1 sysexCallbackFunction 14 14 15 15 ####################################### … … 17 17 ####################################### 18 18 19 begin KEYWORD2 20 begin KEYWORD2 21 printVersion KEYWORD2 22 blinkVersion KEYWORD2 23 printFirmwareVersion KEYWORD2 24 setFirmwareVersion KEYWORD2 19 begin KEYWORD2 20 printVersion KEYWORD2 21 blinkVersion KEYWORD2 22 printFirmwareVersion KEYWORD2 23 setFirmwareVersion KEYWORD2 25 24 setFirmwareNameAndVersion KEYWORD2 26 available KEYWORD2 27 processInput KEYWORD2 28 sendAnalog KEYWORD2 29 sendDigital KEYWORD2 30 sendDigitalPortPair KEYWORD2 31 sendDigitalPort KEYWORD2 32 sendString KEYWORD2 33 sendString KEYWORD2 34 sendSysex KEYWORD2 35 attach KEYWORD2 36 detach KEYWORD2 37 flush KEYWORD2 25 available KEYWORD2 26 processInput KEYWORD2 27 isParsingMessage KEYWORD2 28 parse KEYWORD2 29 sendAnalog KEYWORD2 30 sendDigital KEYWORD2 31 sendDigitalPort KEYWORD2 32 sendString KEYWORD2 33 sendSysex KEYWORD2 34 getPinMode KEYWORD2 35 setPinMode KEYWORD2 36 getPinState KEYWORD2 37 setPinState KEYWORD2 38 attach KEYWORD2 39 detach KEYWORD2 40 write KEYWORD2 41 sendValueAsTwo7bitBytes KEYWORD2 42 startSysex KEYWORD2 43 endSysex KEYWORD2 44 writePort KEYWORD2 45 readPort KEYWORD2 46 disableBlinkVersion KEYWORD2 38 47 39 48 … … 42 51 ####################################### 43 52 44 MAX_DATA_BYTES LITERAL1 53 FIRMATA_MAJOR_VERSION LITERAL1 54 FIRMATA_MINOR_VERSION LITERAL1 55 FIRMATA_BUGFIX_VERSION LITERAL1 45 56 46 DIGITAL_MESSAGE LITERAL1 47 ANALOG_MESSAGE LITERAL1 48 REPORT_ANALOG LITERAL1 49 REPORT_DIGITAL LITERAL1 50 REPORT_VERSION LITERAL1 51 SET_PIN_MODE LITERAL1 52 SYSTEM_RESET LITERAL1 57 MAX_DATA_BYTES LITERAL1 53 58 54 START_SYSEX LITERAL1 55 END_SYSEX LITERAL1 59 DIGITAL_MESSAGE LITERAL1 60 ANALOG_MESSAGE LITERAL1 61 REPORT_ANALOG LITERAL1 62 REPORT_DIGITAL LITERAL1 63 REPORT_VERSION LITERAL1 64 SET_PIN_MODE LITERAL1 65 SET_DIGITAL_PIN_VALUE LITERAL1 66 SYSTEM_RESET LITERAL1 67 START_SYSEX LITERAL1 68 END_SYSEX LITERAL1 69 REPORT_FIRMWARE LITERAL1 70 STRING_DATA LITERAL1 56 71 57 PWM LITERAL1 72 PIN_MODE_ANALOG LITERAL1 73 PIN_MODE_PWM LITERAL1 74 PIN_MODE_SERVO LITERAL1 75 PIN_MODE_SHIFT LITERAL1 76 PIN_MODE_I2C LITERAL1 77 PIN_MODE_ONEWIRE LITERAL1 78 PIN_MODE_STEPPER LITERAL1 79 PIN_MODE_ENCODER LITERAL1 80 PIN_MODE_SERIAL LITERAL1 81 PIN_MODE_PULLUP LITERAL1 82 PIN_MODE_IGNORE LITERAL1 58 83 84 TOTAL_PINS LITERAL1 59 85 TOTAL_ANALOG_PINS LITERAL1 60 86 TOTAL_DIGITAL_PINS LITERAL1 61 TOTAL_PORTS LITERAL1 62 ANALOG_PORT LITERAL1 87 TOTAL_PIN_MODES LITERAL1 88 TOTAL_PORTS LITERAL1 89 ANALOG_PORT LITERAL1 90 MAX_SERVOS LITERAL1 -
rtos_arduino/trunk/arduino_lib/libraries/Firmata/library.properties
r136 r224 1 1 name=Firmata 2 version=2. 3.62 version=2.5.2 3 3 author=Firmata Developers 4 maintainer= Firmata Developers <firmata-devel@lists.sourceforge.net>4 maintainer=https://github.com/firmata/arduino 5 5 sentence=Enables the communication with computer apps using a standard serial protocol. For all Arduino boards. 6 6 paragraph=The Firmata library implements the Firmata protocol for communicating with software on the host computer. This allows you to write custom firmware without having to create your own protocol and objects for the programming environment that you are using. 7 7 category=Device Control 8 url=http ://firmata.org8 url=https://github.com/firmata/arduino 9 9 architectures=* -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/examples/LuckyTest/LuckyTest.ino
r175 r224 79 79 80 80 //read magnetometer sensor 81 lucky.magnetometer().read(); 81 82 Serial.print("Mx: "); 82 83 Serial.print(lucky.magnetometer().x()); -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/library.properties
r175 r224 1 1 name=Lucky Shield 2 version=1.0. 22 version=1.0.3 3 3 author=Arduino srl 4 4 maintainer=Arduino srl <swdev@arduino.org> -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/Lucky.h
r175 r224 40 40 #include "Wire.h" 41 41 42 #ifdef __SAM3X8E__ 43 #define Wire Wire1 44 #endif 45 42 46 class Lucky 43 47 { -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/Adafruit_SSD1306.cpp
r175 r224 32 32 #include "Adafruit_SSD1306.h" 33 33 34 #ifdef __SAM3X8E__ 35 #define Wire Wire1 36 #endif 34 37 // the memory buffer for the LCD 35 38 -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/Adafruit_SSD1306.h
r175 r224 164 164 int8_t _i2caddr, _vccstate, sid, sclk, dc, rst, cs; 165 165 166 boolean hwSPI;167 PortReg *mosiport, *clkport, *csport, *dcport;168 PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask;166 //boolean hwSPI; 167 //PortReg *mosiport, *clkport, *csport, *dcport; 168 //PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask; 169 169 170 170 inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline)); -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/BME280.cpp
r175 r224 19 19 #include "BME280.h" 20 20 21 #ifdef __SAM3X8E__ 22 #define Wire Wire1 23 #endif 21 24 22 25 /*************************************************************************** -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/CAT9555.cpp
r175 r224 28 28 #include "CAT9555.h" 29 29 #include <Wire.h> 30 31 #ifdef __SAM3X8E__ 32 #define Wire Wire1 33 #endif 30 34 31 35 // CONSTRUCTUR -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/MAG3110.cpp
r175 r224 16 16 17 17 //Constructor 18 MAG3110::MAG3110() 19 { 20 21 } 22 23 18 // MAG3110::MAG3110() 19 // { 20 // } 24 21 25 22 // Configure magnetometer 26 23 void MAG3110::begin(void) { 27 //CTRL_REG1 28 //DR2|DR1|DR0|OS1|OS0|FastRead|Trigger|ActiveMode| 29 // 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |=dec121 24 30 25 Wire.beginTransmission(MAG_ADDR);// transmit to device 0x0E 31 Wire.write(0x1 0); // cntrl register132 Wire.write(0x 79); // Active Mode, 1.25 Hz datarate, 8x oversampling33 Wire.endTransmission(); 26 Wire.write(0x11); // cntrl register2 27 Wire.write(0x80); // send 0x80, enable auto resets 28 Wire.endTransmission(); // stop transmitting 34 29 35 30 delay(15); 36 31 37 //CTRL_REG2:38 //AutoMagRst|---|Raw|Mag_Rst|---|---|---|---|39 // 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |40 32 Wire.beginTransmission(MAG_ADDR);// transmit to device 0x0E 41 Wire.write(0x1 1); // cntrl register242 Wire.write( 0x80); // Auto resets before each measurement43 Wire.endTransmission(); 33 Wire.write(0x10); // cntrl register1 34 Wire.write(1); // send 0x01, active mode 35 Wire.endTransmission(); // stop transmitting 44 36 } 45 37 38 void MAG3110::read() 39 { 40 mag_x =read16Data(0x01,0x02); 41 mag_y =read16Data(0x03,0x04); 42 mag_z =read16Data(0x05,0x06); 43 } 44 // read X value 46 45 47 // read X value 48 int MAG3110::readx(void) 46 int MAG3110::read16Data(byte MSB, byte LSB) 49 47 { 50 48 int xl, xh; //define the MSB and LSB 51 49 52 50 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E 53 Wire.write( 0x01); // x MSB reg51 Wire.write(MSB); // x MSB reg 54 52 Wire.endTransmission(); // stop transmitting 55 53 … … 65 63 66 64 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E 67 Wire.write( 0x02); // x LSB reg65 Wire.write(LSB); // x LSB reg 68 66 Wire.endTransmission(); // stop transmitting 69 67 … … 76 74 } 77 75 78 int xout = (xl|(xh << 8)); //concatenate the MSB and LSB 79 return xout; 76 int out = (xl|(xh << 8)); //concatenate the MSB and LSB 77 if (out & 0b1000000000000000){ 78 //float yout1 = ((~yout & 0b0111111111111111)+ 1)*(-1) ; 79 return float ((~out & 0b0111111111111111)+ 1)*(-1) ; 80 } 81 return float (out); 80 82 } 81 83 82 //read Y value83 int MAG3110::ready(void)84 {85 int yl, yh; //define the MSB and LSB86 87 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E88 Wire.write(0x03); // y MSB reg89 Wire.endTransmission(); // stop transmitting90 91 delayMicroseconds(2); //needs at least 1.3us free time between start and stop92 93 Wire.requestFrom(MAG_ADDR, 1); // request 1 byte94 while(Wire.available()) // slave may send less than requested95 {96 yh = Wire.read(); // receive the byte97 }98 99 delayMicroseconds(2); //needs at least 1.3us free time between start and stop100 101 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E102 Wire.write(0x04); // y LSB reg103 Wire.endTransmission(); // stop transmitting104 105 delayMicroseconds(2); //needs at least 1.3us free time between start and stop106 107 Wire.requestFrom(MAG_ADDR, 1); // request 1 byte108 while(Wire.available()) // slave may send less than requested109 {110 yl = Wire.read(); // receive the byte111 }112 113 int yout = (yl|(yh << 8)); //concatenate the MSB and LSB114 return yout;115 }116 117 // read Z value118 int MAG3110::readz(void)119 {120 int zl, zh; //define the MSB and LSB121 122 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E123 Wire.write(0x05); // z MSB reg124 Wire.endTransmission(); // stop transmitting125 126 delayMicroseconds(2); //needs at least 1.3us free time between start and stop127 128 Wire.requestFrom(MAG_ADDR, 1); // request 1 byte129 while(Wire.available()) // slave may send less than requested130 {131 zh = Wire.read(); // receive the byte132 }133 134 delayMicroseconds(2); //needs at least 1.3us free time between start and stop135 136 Wire.beginTransmission(MAG_ADDR); // transmit to device 0x0E137 Wire.write(0x06); // z LSB reg138 Wire.endTransmission(); // stop transmitting139 140 delayMicroseconds(2); //needs at least 1.3us free time between start and stop141 142 Wire.requestFrom(MAG_ADDR, 1); // request 1 byte143 while(Wire.available()) // slave may send less than requested144 {145 zl = Wire.read(); // receive the byte146 }147 148 int zout = (zl|(zh << 8)); //concatenate the MSB and LSB149 return zout;150 }151 84 152 85 MAG3110 mag3110; -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/MAG3110.h
r175 r224 25 25 { 26 26 public: 27 MAG3110(); 27 //constructor 28 //MAG3110(); 29 30 //public methods 28 31 void begin(); 29 int readx(); 30 int ready(); 31 int readz(); 32 33 int x(){return readx();}; 34 int y(){return ready();}; 35 int z(){return readz();}; 32 void read(); 33 int x(){return mag_x;}; 34 int y(){return mag_y;}; 35 int z(){return mag_z;}; 36 36 37 private: 38 //class-only methods: 39 int read16Data(byte MSB, byte LSB); 40 41 //global variables 42 int mag_x; 43 int mag_y; 44 int mag_z; 45 37 46 }; 38 47 -
rtos_arduino/trunk/arduino_lib/libraries/LuckyShield/src/lib/MMA8491Q.cpp
r175 r224 30 30 #include "MMA8491Q.h" 31 31 #include <Wire.h> 32 33 #ifdef __SAM3X8E__ 34 #define Wire Wire1 35 #endif 32 36 33 37 // CONSTRUCTUR -
rtos_arduino/trunk/arduino_lib/libraries/Servo/src/Servo.h
r136 r224 66 66 #elif defined(ARDUINO_ARCH_SAMD) 67 67 //#include "samd/ServoTimersSamd.h" 68 #define MIN_PULSE_WIDTH_SAMD 500 69 #define MAX_PULSE_WIDTH_SAMD 2100 68 #define MIN_PULSE_WIDTH_SAMD_TCC 405 69 #define MAX_PULSE_WIDTH_SAMD_TCC 2300 70 #define MIN_PULSE_WIDTH_SAMD_TC 1700 71 #define MAX_PULSE_WIDTH_SAMD_TC 9200 70 72 #else 71 73 #error "This library only supports boards with an AVR,SAM or SAMD processor." -
rtos_arduino/trunk/arduino_lib/libraries/Servo/src/samd/Servo.cpp
r136 r224 16 16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 17 */ 18 //Edited by Arduino Srl development team. 18 19 19 20 #if defined(ARDUINO_ARCH_SAMD) … … 22 23 #include <Servo.h> 23 24 25 24 26 static servo_t servos[MAX_SERVOS]; // static array of servo structures 25 27 26 28 uint8_t ServoCount = 0; // the total number of attached servos 29 uint8_t isTC = 0 ; 30 Tc* TCx ; 27 31 Tcc* TCCx; 28 32 uint8_t Channelx = 0; … … 30 34 // convenience macros 31 35 32 #define SERVO_MIN() (MIN_PULSE_WIDTH_SAMD) // minimum value in uS for this servo 33 #define SERVO_MAX() (MAX_PULSE_WIDTH_SAMD) // maximum value in uS for this servo 36 #define SERVO_MIN_TCC() (MIN_PULSE_WIDTH_SAMD_TCC) // minimum value in uS for this servo if TCC timer is used 37 #define SERVO_MAX_TCC() (MAX_PULSE_WIDTH_SAMD_TCC) // maximum value in uS for this servo if TCC timer is used 38 #define SERVO_MIN_TC() (MIN_PULSE_WIDTH_SAMD_TC) // minimum value in uS for this servo if TC timer is used 39 #define SERVO_MAX_TC() (MAX_PULSE_WIDTH_SAMD_TC) // maximum value in uS for this servo if TC timer is used 34 40 35 41 /************ static functions common to all instances ***********************/ … … 46 52 if (ServoCount < MAX_SERVOS) { 47 53 this->servoIndex = ServoCount++; // assign a servo index to this instance 48 } else { //su questo costruttore forse si deve tornare49 this->servoIndex = INVALID_SERVO; // too many servos54 } else { 55 this->servoIndex = INVALID_SERVO; // too many servos 50 56 } 51 57 } … … 53 59 uint8_t Servo::attach(int pin) 54 60 { 55 return this->attach(pin, MIN_PULSE_WIDTH_SAMD, MAX_PULSE_WIDTH_SAMD); 61 if((servos[this->servoIndex].Pin.nbr==4) | (servos[this->servoIndex].Pin.nbr==5) | (servos[this->servoIndex].Pin.nbr==10) | (servos[this->servoIndex].Pin.nbr==12) ){ 62 return this->attach(pin, SERVO_MIN_TC(), SERVO_MAX_TC()); 63 } 64 else{ 65 return this->attach(pin, SERVO_MIN_TCC(), SERVO_MAX_TCC()); 66 } 56 67 } 57 68 … … 63 74 pinMode(pin, OUTPUT); // set servo pin to output 64 75 servos[this->servoIndex].Pin.nbr = pin; 65 if(min > MIN_PULSE_WIDTH_SAMD) min = MIN_PULSE_WIDTH_SAMD; 66 if (max > MAX_PULSE_WIDTH_SAMD) max = MAX_PULSE_WIDTH_SAMD; 76 int servo_min, servo_max; 77 if(pin==4 | pin==5 | pin==10 | pin==12){ 78 servo_min=SERVO_MIN_TC(); 79 servo_max=SERVO_MAX_TC(); 80 } 81 else{ 82 servo_min=SERVO_MIN_TCC(); 83 servo_max=SERVO_MAX_TCC(); 84 } 85 if(min > servo_min) min = servo_min; 86 if (max > servo_max) max = servo_max; 67 87 this->min = min; 68 88 this->max = max; … … 75 95 TCCx=TCC0; 76 96 Channelx=0; 97 isTC=0; 77 98 } 78 99 break; … … 83 104 TCCx=TCC0; 84 105 Channelx=1; 85 } 86 break; 87 106 isTC=0; 107 } 108 break; 109 110 case 4: 111 { 112 pinPeripheral(pin, g_APinDescription[pin].ulPinType); 113 TCx=TC3; 114 Channelx=0; 115 isTC=1; 116 117 } 118 break; 119 120 case 5: 121 { 122 pinPeripheral(pin, g_APinDescription[pin].ulPinType); 123 TCx=TC3; 124 Channelx=1; 125 isTC=1; 126 127 } 128 break; 88 129 case 6: 89 130 { … … 91 132 TCCx=TCC0; 92 133 Channelx=2; 134 isTC=0; 93 135 } 94 136 break; … … 99 141 TCCx=TCC0; 100 142 Channelx=3; 143 isTC=0; 101 144 } 102 145 break; … … 107 150 TCCx=TCC1; 108 151 Channelx=0; 152 isTC=0; 109 153 } 110 154 break; … … 115 159 TCCx=TCC1; 116 160 Channelx=1; 161 isTC=0; 162 } 163 break; 164 165 case 10: 166 { 167 pinPeripheral(pin, g_APinDescription[pin].ulPinType); 168 TCx=TC3; 169 Channelx=0; 170 isTC=1; 171 117 172 } 118 173 break; … … 123 178 TCCx=TCC2; 124 179 Channelx=0; 180 isTC=0; 181 } 182 break; 183 184 case 12: 185 { 186 pinPeripheral(pin, g_APinDescription[pin].ulPinType); 187 TCx=TC3; 188 Channelx=1; 189 isTC=1; 190 125 191 } 126 192 break; … … 131 197 TCCx=TCC2; 132 198 Channelx=1; 199 isTC=0; 133 200 } 134 201 break; … … 140 207 141 208 if ((TCCx==TCC0) | (TCCx==TCC1)) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; 142 else if( TCCx==TCC2)GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ;209 else if((TCCx==TCC2) | (TCx==TC3 ))GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK3 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ; 143 210 else; 144 145 if(servos[this->servoIndex].Pin.isActive == false) 146 { 147 TCCx->CTRLA.reg &=~(TCC_CTRLA_ENABLE); //disable TCC module 211 212 if(servos[this->servoIndex].Pin.isActive == false){ 213 // Set PORT 214 if ( isTC ) 215 { 216 // -- Configure TC 217 //DISABLE TCx 218 TCx->COUNT16.CTRLA.reg &=~(TC_CTRLA_ENABLE); 219 //Set Timer counter Mode to 16 bits 220 TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; 221 //Set Prescaler to divide by 2 222 TCx->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV2; 223 //Set TCx as normal PWM 224 TCx->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; 225 //default value for servo position 226 TCx->COUNT16.CC[Channelx].reg = 1500; 227 //ENABLE TCx 228 TCx->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; 229 servos[this->servoIndex].Pin.isActive = true; 230 } 231 else 232 { 233 // -- Configure TCC 234 235 TCCx->CTRLA.reg &=~(TCC_CTRLA_ENABLE); //disable TCC module 148 236 TCCx->CTRLA.reg |=TCC_CTRLA_PRESCALER_DIV8; //setting prescaler to divide by 8 149 237 TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; //Set TCCx as normal PWM … … 151 239 TCCx->PER.reg=20000; // setting servo frequency (50 hz) 152 240 TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ; //ENABLE TCCx 153 servos[this->servoIndex].Pin.isActive = true; 154 } 155 156 //servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive 241 servos[this->servoIndex].Pin.isActive = true; 242 } 243 244 } 157 245 } 158 246 return this->servoIndex; … … 167 255 else if((servos[this->servoIndex].Pin.nbr == 8) | (servos[this->servoIndex].Pin.nbr == 9)) TCC1->CTRLA.reg &=~(TCC_CTRLA_ENABLE); 168 256 else if ((servos[this->servoIndex].Pin.nbr == 11) | (servos[this->servoIndex].Pin.nbr == 13)) TCC2->CTRLA.reg &=~(TCC_CTRLA_ENABLE); 257 else if ((servos[this->servoIndex].Pin.nbr == 4 ) | (servos[this->servoIndex].Pin.nbr == 5 ) | (servos[this->servoIndex].Pin.nbr == 10 ) | (servos[this->servoIndex].Pin.nbr == 12 ))TC3->COUNT16.CTRLA.reg &=~(TC_CTRLA_ENABLE); 169 258 } 170 259 171 260 void Servo::write(int value) 172 { 173 // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) 174 if (value < MIN_PULSE_WIDTH) 175 { 176 if (value < 0) 177 value = 0; 178 else if (value > 180) 179 value = 180; 180 181 value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); 182 } 261 { 262 //select the right values for servo motor 263 int servo_min; 264 int servo_max; 265 if((servos[this->servoIndex].Pin.nbr==4) | (servos[this->servoIndex].Pin.nbr==5) | (servos[this->servoIndex].Pin.nbr==10) | (servos[this->servoIndex].Pin.nbr==12) ){ 266 servo_min=SERVO_MIN_TC(); 267 servo_max=SERVO_MAX_TC(); 268 // treat values less than 1700 as angles in degrees (valid values in microseconds are handled as microseconds) 269 if (value < servo_min) 270 { 271 if (value < 0) 272 value = 0; 273 else if (value > 180) 274 value = 180; 275 value = map(value, 0, 180, servo_min, servo_max); 276 } 277 } 278 else{ 279 servo_min=SERVO_MIN_TCC(); 280 servo_max=SERVO_MAX_TCC(); 281 // treat values less than 400 as angles in degrees (valid values in microseconds are handled as microseconds) 282 if (value < servo_min) 283 { 284 if (value < 0) 285 value = 0; 286 else if (value > 180) 287 value = 180; 288 value = map(value, 0, 180, servo_min, servo_max); 289 } 290 } 291 183 292 writeMicroseconds(value); 184 293 } … … 190 299 if( (channel < MAX_SERVOS) ) // ensure channel is valid 191 300 { 192 if (value < SERVO_MIN()) // ensure pulse width is valid 193 value = SERVO_MIN(); 194 else if (value > SERVO_MAX()) 195 value = SERVO_MAX(); 196 servos[this->servoIndex].ticks = value; //da sistemare 301 //select the right values for servo motor 302 int servo_min; 303 int servo_max; 304 if((servos[this->servoIndex].Pin.nbr==4) | (servos[this->servoIndex].Pin.nbr==5) | (servos[this->servoIndex].Pin.nbr==10) | (servos[this->servoIndex].Pin.nbr==12) ){ 305 servo_min=SERVO_MIN_TC(); 306 servo_max=SERVO_MAX_TC(); 307 } 308 else{ 309 servo_min=SERVO_MIN_TCC(); 310 servo_max=SERVO_MAX_TCC(); 311 } 312 if (value < servo_min) // ensure pulse width is valid 313 value = servo_min; 314 else if (value > servo_max) 315 value = servo_max; 316 servos[this->servoIndex].ticks = value; 197 317 switch(servos[this->servoIndex].Pin.nbr) 198 318 { … … 205 325 break; 206 326 327 case 4: 328 TC3->COUNT16.CC[0].reg = value; 329 break; 330 331 case 5: 332 TC3->COUNT16.CC[1].reg = value; 333 break; 334 207 335 case 6: 208 336 TCC0->CC[2].reg=value; … … 220 348 TCC1->CC[1].reg=value; 221 349 break; 350 351 case 10: 352 TC3->COUNT16.CC[0].reg = value; 353 break; 222 354 223 355 case 11: … … 225 357 break; 226 358 359 case 12: 360 TC3->COUNT16.CC[1].reg = value; 361 break; 362 227 363 case 13: 228 364 TCC2->CC[1].reg=value; … … 234 370 } 235 371 236 //servos[this->servoIndex].ticks = value; // da sistemare372 //servos[this->servoIndex].ticks = value; //to be fixed 237 373 //servos[channel].ticks = value; 238 374 } … … 241 377 int Servo::read() // return the value as degrees 242 378 { 243 return map(readMicroseconds(), SERVO_MIN(), SERVO_MAX(), 0, 180); 379 //select the right values for servo motor 380 int servo_min; 381 int servo_max; 382 if((servos[this->servoIndex].Pin.nbr==4) | (servos[this->servoIndex].Pin.nbr==5) | (servos[this->servoIndex].Pin.nbr==10) | (servos[this->servoIndex].Pin.nbr==12) ){ 383 servo_min=SERVO_MIN_TC(); 384 servo_max=SERVO_MAX_TC(); 385 } 386 else{ 387 servo_min=SERVO_MIN_TCC(); 388 servo_max=SERVO_MAX_TCC(); 389 } 390 return map(readMicroseconds(), servo_min, servo_max, 0, 180); 244 391 } 245 392
Note:
See TracChangeset
for help on using the changeset viewer.