From 5d06a6128286d27a424765766590ab4f56d0ed59 Mon Sep 17 00:00:00 2001 From: Fontaine Date: Thu, 8 Oct 2020 21:40:35 +0200 Subject: [PATCH] version 1.9 --- build/app.icns | Bin 0 -> 5259 bytes build/bf.icns | Bin 0 -> 4257 bytes build/bloc.icns | Bin 0 -> 5489 bytes build/html.icns | Bin 0 -> 7285 bytes build/ino.icns | Bin 0 -> 11982 bytes build/py.icns | Bin 0 -> 5745 bytes build/www.icns | Bin 0 -> 7915 bytes .../arduino/libraries/Esplora/Esplora.cpp | 184 +++ .../arduino/libraries/Esplora/Esplora.h | 177 +++ .../arduino/libraries/IRremote/IRremote.cpp | 1154 +++++++++++++++++ .../arduino/libraries/IRremote/IRremote.h | 128 ++ .../arduino/libraries/IRremote/IRremoteInt.h | 515 ++++++++ .../arduino/libraries/extension/extension.cpp | 178 ++- .../arduino/libraries/extension/extension.h | 24 +- package.json | 11 +- www/accueil.html | 51 - www/blocs&generateurs/_actionneur.js | 24 +- www/blocs&generateurs/_microbit.js | 7 +- .../arduino_generateurs_cpp.js | 2 +- www/blocs&generateurs/factory/add.js | 13 - www/blocs&generateurs/factory/append.js | 1 + www/blocs&generateurs/factory/generator.js | 49 +- www/factory.html | 4 + www/index.html | 89 +- www/js/blocklino.js | 22 +- www/lang/Arduino_en.js | 2 + www/lang/Arduino_fr.js | 4 +- www/lang/code.js | 2 + www/lang/msg_en.js | 4 +- www/lang/msg_fr.js | 2 + www/modalVar.html | 1 - www/splash.html | 11 - www/toolbox/toolbox_arduino_all.xml | 55 +- 33 files changed, 2438 insertions(+), 276 deletions(-) create mode 100644 build/app.icns create mode 100644 build/bf.icns create mode 100644 build/bloc.icns create mode 100644 build/html.icns create mode 100644 build/ino.icns create mode 100644 build/py.icns create mode 100644 build/www.icns create mode 100644 compilation/arduino/libraries/Esplora/Esplora.cpp create mode 100644 compilation/arduino/libraries/Esplora/Esplora.h create mode 100644 compilation/arduino/libraries/IRremote/IRremote.cpp create mode 100644 compilation/arduino/libraries/IRremote/IRremote.h create mode 100644 compilation/arduino/libraries/IRremote/IRremoteInt.h delete mode 100644 www/accueil.html delete mode 100644 www/blocs&generateurs/factory/add.js delete mode 100644 www/splash.html diff --git a/build/app.icns b/build/app.icns new file mode 100644 index 0000000000000000000000000000000000000000..6f6b1ce64ebfeeb6c91b1077eea432b3077ca4cc GIT binary patch literal 5259 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 literal 0 HcmV?d00001 diff --git a/build/bf.icns b/build/bf.icns new file mode 100644 index 0000000000000000000000000000000000000000..3e619f1f37c9ffc92efa90c54d059cc393bb2692 GIT binary patch literal 4257 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 literal 0 HcmV?d00001 diff --git a/build/bloc.icns b/build/bloc.icns new file mode 100644 index 0000000000000000000000000000000000000000..7e2489a1cf360ecd7f96f8623ef6fea215fc74e3 GIT binary patch literal 5489 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 literal 0 HcmV?d00001 diff --git a/build/html.icns b/build/html.icns new file mode 100644 index 0000000000000000000000000000000000000000..14adccc06010fb6dbbbdd584b90a0a14d8f459fc GIT binary patch literal 7285 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�o3+Rj}?vN}F46gSYzK@|R~$l+BpW7l*@ zJrU;b?v5@~5d*uP%u%f%W&hR*p8>Y`O^L&_k7hv%Y~Lb6S$4X7CMZGn^=IoY#-w(4Asgc-HN z_`fU_JzW2UAvC-XnpCZ%?)?LuZ*>ifR zs$#oU+Q22hvfa*41=;;+1^kJ^QIOu=EF5OG?Hf%Du?)d4DkP|&AiA-pwJB*((S#`; z8_KS!&-?e3o>$iz)?U1;Qf0awXFpJG9>f4%&VPY6_sJ*tMfA z!mze5gjcYw02*DQRN~NIW#kjB4^T<#m?qq?V43hNov!u$_XMco#qT)O~2Y zINk7@OX1E%)vNi%Kqtexsi~=soE);zdtNRsNKdjLc0Cs(G>;;-OF5_G9sCVvbaZsq zKSzGk#c6qbrP-uXxAwSUpek!9whX#~48|uQnA%PhJ#Ky)aYP?*)KycP(ACh`LLQ}; zhJfN|>H;1yHr;6>Xtt%!qlr zE)vz1E9kY?G;e%SF7ih`oLg8k!|=*+pF literal 0 HcmV?d00001 diff --git a/build/py.icns b/build/py.icns new file mode 100644 index 0000000000000000000000000000000000000000..6cccd16dec8b087369163b431bd22ec0c8dff256 GIT binary patch literal 5745 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 literal 0 HcmV?d00001 diff --git a/compilation/arduino/libraries/Esplora/Esplora.cpp b/compilation/arduino/libraries/Esplora/Esplora.cpp new file mode 100644 index 00000000..a8089444 --- /dev/null +++ b/compilation/arduino/libraries/Esplora/Esplora.cpp @@ -0,0 +1,184 @@ +/* + Esplora.cpp - Arduino Esplora board library + Written by Enrico Gueli + Copyright (c) 2012 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + + +#include "Esplora.h" + +_Esplora Esplora; + +/* + * The following constants tell, for each accelerometer + * axis, which values are returned when the axis measures + * zero acceleration. + */ +const int ACCEL_ZERO_X = 320; +const int ACCEL_ZERO_Y = 330; +const int ACCEL_ZERO_Z = 310; + +const byte MUX_ADDR_PINS[] = { A0, A1, A2, A3 }; +const byte MUX_COM_PIN = A4; + +const int JOYSTICK_DEAD_ZONE = 100; + +const byte RED_PIN = 5; +const byte BLUE_PIN = 9; +const byte GREEN_PIN = 10; + +const byte BUZZER_PIN = 6; + +// non-multiplexer Esplora pins: +// Accelerometer: x-A5, y-A11, z-A6 +// External outputs: D3, D11 +// Buzzer: D6 +// RGB Led: red-D5, green-D10, blue-D9 +// Led 13: D13 + +const byte ACCEL_X_PIN = A5; +const byte ACCEL_Y_PIN = A11; +const byte ACCEL_Z_PIN = A6; + +const byte LED_PIN = 13; + +_Esplora::_Esplora() { + for (byte p=0; p<4; p++) { + pinMode(MUX_ADDR_PINS[p], OUTPUT); + } + pinMode(RED_PIN, OUTPUT); + pinMode(GREEN_PIN, OUTPUT); + pinMode(BLUE_PIN, OUTPUT); +} + +unsigned int _Esplora::readChannel(byte channel) { + digitalWrite(MUX_ADDR_PINS[0], (channel & 1) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[1], (channel & 2) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[2], (channel & 4) ? HIGH : LOW); + digitalWrite(MUX_ADDR_PINS[3], (channel & 8) ? HIGH : LOW); + // workaround to cope with lack of pullup resistor on joystick switch + if (channel == CH_JOYSTICK_SW) { + pinMode(MUX_COM_PIN, INPUT_PULLUP); + unsigned int joystickSwitchState = (digitalRead(MUX_COM_PIN) == HIGH) ? 1023 : 0; + digitalWrite(MUX_COM_PIN, LOW); + return joystickSwitchState; + } + else + return analogRead(MUX_COM_PIN); +} + +boolean _Esplora::joyLowHalf(byte joyCh) { + return (readChannel(joyCh) < 512 - JOYSTICK_DEAD_ZONE) + ? LOW : HIGH; +} + +boolean _Esplora::joyHighHalf(byte joyCh) { + return (readChannel(joyCh) > 512 + JOYSTICK_DEAD_ZONE) + ? LOW : HIGH; +} + +boolean _Esplora::readButton(byte ch) { + if (ch >= SWITCH_1 && ch <= SWITCH_4) { + ch--; + } + + switch(ch) { + case JOYSTICK_RIGHT: + return joyLowHalf(CH_JOYSTICK_X); + case JOYSTICK_LEFT: + return joyHighHalf(CH_JOYSTICK_X); + case JOYSTICK_UP: + return joyLowHalf(CH_JOYSTICK_Y); + case JOYSTICK_DOWN: + return joyHighHalf(CH_JOYSTICK_Y); + } + + unsigned int val = readChannel(ch); + return (val > 512) ? HIGH : LOW; +} + +boolean _Esplora::readJoystickButton() { + if (readChannel(CH_JOYSTICK_SW) == 1023) { + return HIGH; + } else if (readChannel(CH_JOYSTICK_SW) == 0) { + return LOW; + } +} + + +void _Esplora::writeRGB(byte r, byte g, byte b) { + writeRed(r); + writeGreen(g); + writeBlue(b); +} + +#define RGB_FUNC(name, pin, lastVar) \ +void _Esplora::write##name(byte val) { \ + if (val == lastVar) \ + return; \ + analogWrite(pin, val); \ + lastVar = val; \ + delay(5); \ +} \ +\ +byte _Esplora::read##name() { \ + return lastVar; \ +} + +RGB_FUNC(Red, RED_PIN, lastRed) +RGB_FUNC(Green, GREEN_PIN, lastGreen) +RGB_FUNC(Blue, BLUE_PIN, lastBlue) + +void _Esplora::tone(unsigned int freq) { + if (freq > 0) + ::tone(BUZZER_PIN, freq); + else + ::noTone(BUZZER_PIN); +} + +void _Esplora::tone(unsigned int freq, unsigned long duration) { + if (freq > 0) + ::tone(BUZZER_PIN, freq, duration); + else + ::noTone(BUZZER_PIN); +} + +void _Esplora::noTone() { + ::noTone(BUZZER_PIN); +} + +int _Esplora::readTemperature(const byte scale) { + long rawT = readChannel(CH_TEMPERATURE); + if (scale == DEGREES_C) { + return (int)((rawT * 500 / 1024) - 50); + } + else if (scale == DEGREES_F) { + return (int)((rawT * 450 / 512 ) - 58); + } + else { + return readTemperature(DEGREES_C); + } +} + +int _Esplora::readAccelerometer(const byte axis) { + switch (axis) { + case X_AXIS: return analogRead(ACCEL_X_PIN) - ACCEL_ZERO_X; + case Y_AXIS: return analogRead(ACCEL_Y_PIN) - ACCEL_ZERO_Y; + case Z_AXIS: return analogRead(ACCEL_Z_PIN) - ACCEL_ZERO_Z; + default: return 0; + } +} diff --git a/compilation/arduino/libraries/Esplora/Esplora.h b/compilation/arduino/libraries/Esplora/Esplora.h new file mode 100644 index 00000000..4e59fbe0 --- /dev/null +++ b/compilation/arduino/libraries/Esplora/Esplora.h @@ -0,0 +1,177 @@ +/* + Esplora.h - Arduino Esplora board library + Written by Enrico Gueli + Copyright (c) 2012 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ESPLORA_H_ +#define ESPLORA_H_ + +#include + +/* + * The following constants are used internally by the Esplora + * library code. + */ + +const byte JOYSTICK_BASE = 16; // it's a "virtual" channel: its ID won't conflict with real ones + +const byte MAX_CHANNELS = 13; + +const byte CH_SWITCH_1 = 0; +const byte CH_SWITCH_2 = 1; +const byte CH_SWITCH_3 = 2; +const byte CH_SWITCH_4 = 3; +const byte CH_SLIDER = 4; +const byte CH_LIGHT = 5; +const byte CH_TEMPERATURE = 6; +const byte CH_MIC = 7; +const byte CH_TINKERKIT_A = 8; +const byte CH_TINKERKIT_B = 9; +const byte CH_JOYSTICK_SW = 10; +const byte CH_JOYSTICK_X = 11; +const byte CH_JOYSTICK_Y = 12; + +/* + * The following constants can be used with the readButton() + * method. + */ + +const byte SWITCH_1 = 1; +const byte SWITCH_2 = 2; +const byte SWITCH_3 = 3; +const byte SWITCH_4 = 4; + +const byte SWITCH_DOWN = SWITCH_1; +const byte SWITCH_LEFT = SWITCH_2; +const byte SWITCH_UP = SWITCH_3; +const byte SWITCH_RIGHT = SWITCH_4; + +const byte JOYSTICK_DOWN = JOYSTICK_BASE; +const byte JOYSTICK_LEFT = JOYSTICK_BASE+1; +const byte JOYSTICK_UP = JOYSTICK_BASE+2; +const byte JOYSTICK_RIGHT = JOYSTICK_BASE+3; + +/* + * These constants can be use for comparison with the value returned + * by the readButton() method. + */ +const boolean PRESSED = LOW; +const boolean RELEASED = HIGH; + +/* + * The following constants can be used with the readTemperature() + * method to specify the desired scale. + */ +const byte DEGREES_C = 0; +const byte DEGREES_F = 1; + +/* + * The following constants can be used with the readAccelerometer() + * method to specify the desired axis to return. + */ +const byte X_AXIS = 0; +const byte Y_AXIS = 1; +const byte Z_AXIS = 2; + + +class _Esplora { +private: + byte lastRed; + byte lastGreen; + byte lastBlue; + + unsigned int readChannel(byte channel); + + boolean joyLowHalf(byte joyCh); + boolean joyHighHalf(byte joyCh); + +public: + _Esplora(); + + /* + * Returns a number corresponding to the position of the + * linear potentiometer. 0 means full right, 1023 means + * full left. + */ + inline unsigned int readSlider() { return readChannel(CH_SLIDER); } + + /* + * Returns a number corresponding to the amount of ambient + * light sensed by the light sensor. + */ + inline unsigned int readLightSensor() { return readChannel(CH_LIGHT); } + + /* + * Returns the current ambient temperature, expressed either in Celsius + * or Fahreneit scale. + */ + int readTemperature(const byte scale); + + /* + * Returns a number corresponding to the amount of ambient noise. + */ + inline unsigned int readMicrophone() { return readChannel(CH_MIC); } + + inline unsigned int readJoystickSwitch() { return readChannel(CH_JOYSTICK_SW); } + + inline int readJoystickX() { + return readChannel(CH_JOYSTICK_X) - 512; + } + inline int readJoystickY() { + return readChannel(CH_JOYSTICK_Y) - 512; + } + + int readAccelerometer(const byte axis); + + /* + * Reads the current state of a button. It will return + * LOW if the button is pressed, and HIGH otherwise. + */ + boolean readButton(byte channel); + + boolean readJoystickButton(); + + void writeRGB(byte red, byte green, byte blue); + void writeRed(byte red); + void writeGreen(byte green); + void writeBlue(byte blue); + + byte readRed(); + byte readGreen(); + byte readBlue(); + + void tone(unsigned int freq); + void tone(unsigned int freq, unsigned long duration); + void noTone(); + + inline unsigned int readTinkerkitInput(byte whichInput) { + return readChannel(whichInput + CH_TINKERKIT_A); + } + inline unsigned int readTinkerkitInputA() { + return readChannel(CH_TINKERKIT_A); + } + inline unsigned int readTinkerkitInputB() { + return readChannel(CH_TINKERKIT_B); + } +}; + + + +extern _Esplora Esplora; + +#endif // ESPLORA_H_ diff --git a/compilation/arduino/libraries/IRremote/IRremote.cpp b/compilation/arduino/libraries/IRremote/IRremote.cpp new file mode 100644 index 00000000..888f5e2e --- /dev/null +++ b/compilation/arduino/libraries/IRremote/IRremote.cpp @@ -0,0 +1,1154 @@ +/* + * IRremote + * Version 0.11 August, 2009 + * Copyright 2009 Ken Shirriff + * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html + * + * Modified by Paul Stoffregen to support other boards and timers + * Modified by Mitra Ardron + * Added Sanyo and Mitsubishi controllers + * Modified Sony to spot the repeat codes that some Sony's send + * + * Interrupt code based on NECIRrcv by Joe Knapp + * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 + * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ + * + * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) + * LG added by Darryl Smith (based on the JVC protocol) + */ + +#include "IRremote.h" +#include "IRremoteInt.h" + +// Provides ISR +#include + +volatile irparams_t irparams; + +// These versions of MATCH, MATCH_MARK, and MATCH_SPACE are only for debugging. +// To use them, set DEBUG in IRremoteInt.h +// Normally macros are used for efficiency +#ifdef DEBUG +int MATCH(int measured, int desired) { + Serial.print("Testing: "); + Serial.print(TICKS_LOW(desired), DEC); + Serial.print(" <= "); + Serial.print(measured, DEC); + Serial.print(" <= "); + Serial.println(TICKS_HIGH(desired), DEC); + return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired); +} + +int MATCH_MARK(int measured_ticks, int desired_us) { + Serial.print("Testing mark "); + Serial.print(measured_ticks * USECPERTICK, DEC); + Serial.print(" vs "); + Serial.print(desired_us, DEC); + Serial.print(": "); + Serial.print(TICKS_LOW(desired_us + MARK_EXCESS), DEC); + Serial.print(" <= "); + Serial.print(measured_ticks, DEC); + Serial.print(" <= "); + Serial.println(TICKS_HIGH(desired_us + MARK_EXCESS), DEC); + return measured_ticks >= TICKS_LOW(desired_us + MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us + MARK_EXCESS); +} + +int MATCH_SPACE(int measured_ticks, int desired_us) { + Serial.print("Testing space "); + Serial.print(measured_ticks * USECPERTICK, DEC); + Serial.print(" vs "); + Serial.print(desired_us, DEC); + Serial.print(": "); + Serial.print(TICKS_LOW(desired_us - MARK_EXCESS), DEC); + Serial.print(" <= "); + Serial.print(measured_ticks, DEC); + Serial.print(" <= "); + Serial.println(TICKS_HIGH(desired_us - MARK_EXCESS), DEC); + return measured_ticks >= TICKS_LOW(desired_us - MARK_EXCESS) && measured_ticks <= TICKS_HIGH(desired_us - MARK_EXCESS); +} +#else +int MATCH(int measured, int desired) {return measured >= TICKS_LOW(desired) && measured <= TICKS_HIGH(desired);} +int MATCH_MARK(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us + MARK_EXCESS));} +int MATCH_SPACE(int measured_ticks, int desired_us) {return MATCH(measured_ticks, (desired_us - MARK_EXCESS));} +// Debugging versions are in IRremote.cpp +#endif + +void IRsend::sendNEC(unsigned long data, int nbits) +{ + enableIROut(38); + mark(NEC_HDR_MARK); + space(NEC_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(NEC_BIT_MARK); + space(NEC_ONE_SPACE); + } + else { + mark(NEC_BIT_MARK); + space(NEC_ZERO_SPACE); + } + data <<= 1; + } + mark(NEC_BIT_MARK); + space(0); +} + +void IRsend::sendSony(unsigned long data, int nbits) { + enableIROut(40); + mark(SONY_HDR_MARK); + space(SONY_HDR_SPACE); + data = data << (32 - nbits); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(SONY_ONE_MARK); + space(SONY_HDR_SPACE); + } + else { + mark(SONY_ZERO_MARK); + space(SONY_HDR_SPACE); + } + data <<= 1; + } +} + +void IRsend::sendRaw(unsigned int buf[], int len, int hz) +{ + enableIROut(hz); + for (int i = 0; i < len; i++) { + if (i & 1) { + space(buf[i]); + } + else { + mark(buf[i]); + } + } + space(0); // Just to be sure +} + +// Note: first bit must be a one (start bit) +void IRsend::sendRC5(unsigned long data, int nbits) +{ + enableIROut(36); + data = data << (32 - nbits); + mark(RC5_T1); // First start bit + space(RC5_T1); // Second start bit + mark(RC5_T1); // Second start bit + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + space(RC5_T1); // 1 is space, then mark + mark(RC5_T1); + } + else { + mark(RC5_T1); + space(RC5_T1); + } + data <<= 1; + } + space(0); // Turn off at end +} + +// Caller needs to take care of flipping the toggle bit +void IRsend::sendRC6(unsigned long data, int nbits) +{ + enableIROut(36); + data = data << (32 - nbits); + mark(RC6_HDR_MARK); + space(RC6_HDR_SPACE); + mark(RC6_T1); // start bit + space(RC6_T1); + int t; + for (int i = 0; i < nbits; i++) { + if (i == 3) { + // double-wide trailer bit + t = 2 * RC6_T1; + } + else { + t = RC6_T1; + } + if (data & TOPBIT) { + mark(t); + space(t); + } + else { + space(t); + mark(t); + } + + data <<= 1; + } + space(0); // Turn off at end +} +void IRsend::sendPanasonic(unsigned int address, unsigned long data) { + enableIROut(35); + mark(PANASONIC_HDR_MARK); + space(PANASONIC_HDR_SPACE); + + for(int i=0;i<16;i++) + { + mark(PANASONIC_BIT_MARK); + if (address & 0x8000) { + space(PANASONIC_ONE_SPACE); + } else { + space(PANASONIC_ZERO_SPACE); + } + address <<= 1; + } + for (int i=0; i < 32; i++) { + mark(PANASONIC_BIT_MARK); + if (data & TOPBIT) { + space(PANASONIC_ONE_SPACE); + } else { + space(PANASONIC_ZERO_SPACE); + } + data <<= 1; + } + mark(PANASONIC_BIT_MARK); + space(0); +} +void IRsend::sendJVC(unsigned long data, int nbits, int repeat) +{ + enableIROut(38); + data = data << (32 - nbits); + if (!repeat){ + mark(JVC_HDR_MARK); + space(JVC_HDR_SPACE); + } + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(JVC_BIT_MARK); + space(JVC_ONE_SPACE); + } + else { + mark(JVC_BIT_MARK); + space(JVC_ZERO_SPACE); + } + data <<= 1; + } + mark(JVC_BIT_MARK); + space(0); +} + +void IRsend::sendSAMSUNG(unsigned long data, int nbits) +{ + enableIROut(38); + mark(SAMSUNG_HDR_MARK); + space(SAMSUNG_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & TOPBIT) { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ONE_SPACE); + } + else { + mark(SAMSUNG_BIT_MARK); + space(SAMSUNG_ZERO_SPACE); + } + data <<= 1; + } + mark(SAMSUNG_BIT_MARK); + space(0); +} + +void IRsend::mark(int time) { + // Sends an IR mark for the specified number of microseconds. + // The mark output is modulated at the PWM frequency. + TIMER_ENABLE_PWM; // Enable pin 3 PWM output + if (time > 0) delayMicroseconds(time); +} + +/* Leave pin off for time (given in microseconds) */ +void IRsend::space(int time) { + // Sends an IR space for the specified number of microseconds. + // A space is no output, so the PWM output is disabled. + TIMER_DISABLE_PWM; // Disable pin 3 PWM output + if (time > 0) delayMicroseconds(time); +} + +void IRsend::enableIROut(int khz) { + // Enables IR output. The khz value controls the modulation frequency in kilohertz. + // The IR output will be on pin 3 (OC2B). + // This routine is designed for 36-40KHz; if you use it for other values, it's up to you + // to make sure it gives reasonable results. (Watch out for overflow / underflow / rounding.) + // TIMER2 is used in phase-correct PWM mode, with OCR2A controlling the frequency and OCR2B + // controlling the duty cycle. + // There is no prescaling, so the output frequency is 16MHz / (2 * OCR2A) + // To turn the output on and off, we leave the PWM running, but connect and disconnect the output pin. + // A few hours staring at the ATmega documentation and this will all make sense. + // See my Secrets of Arduino PWM at http://arcfn.com/2009/07/secrets-of-arduino-pwm.html for details. + + + // Disable the Timer2 Interrupt (which is used for receiving IR) + TIMER_DISABLE_INTR; //Timer2 Overflow Interrupt + + pinMode(TIMER_PWM_PIN, OUTPUT); + digitalWrite(TIMER_PWM_PIN, LOW); // When not sending PWM, we want it low + + // COM2A = 00: disconnect OC2A + // COM2B = 00: disconnect OC2B; to send signal set to 10: OC2B non-inverted + // WGM2 = 101: phase-correct PWM with OCRA as top + // CS2 = 000: no prescaling + // The top value for the timer. The modulation frequency will be SYSCLOCK / 2 / OCR2A. + TIMER_CONFIG_KHZ(khz); +} + +IRrecv::IRrecv(int recvpin) +{ + irparams.recvpin = recvpin; + irparams.blinkflag = 0; +} + +// initialization +void IRrecv::enableIRIn() { + cli(); + // setup pulse clock timer interrupt + //Prescale /8 (16M/8 = 0.5 microseconds per tick) + // Therefore, the timer interval can range from 0.5 to 128 microseconds + // depending on the reset value (255 to 0) + TIMER_CONFIG_NORMAL(); + + //Timer2 Overflow Interrupt Enable + TIMER_ENABLE_INTR; + + TIMER_RESET; + + sei(); // enable interrupts + + // initialize state machine variables + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; + + // set pin modes + pinMode(irparams.recvpin, INPUT); +} + +// enable/disable blinking of pin 13 on IR processing +void IRrecv::blink13(int blinkflag) +{ + irparams.blinkflag = blinkflag; + if (blinkflag) + pinMode(BLINKLED, OUTPUT); +} + +// TIMER2 interrupt code to collect raw data. +// Widths of alternating SPACE, MARK are recorded in rawbuf. +// Recorded in ticks of 50 microseconds. +// rawlen counts the number of entries recorded so far. +// First entry is the SPACE between transmissions. +// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues. +// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts +ISR(TIMER_INTR_NAME) +{ + TIMER_RESET; + + uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin); + + irparams.timer++; // One more 50us tick + if (irparams.rawlen >= RAWBUF) { + // Buffer overflow + irparams.rcvstate = STATE_STOP; + } + switch(irparams.rcvstate) { + case STATE_IDLE: // In the middle of a gap + if (irdata == MARK) { + if (irparams.timer < GAP_TICKS) { + // Not big enough to be a gap. + irparams.timer = 0; + } + else { + // gap just ended, record duration and start recording transmission + irparams.rawlen = 0; + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_MARK; + } + } + break; + case STATE_MARK: // timing MARK + if (irdata == SPACE) { // MARK ended, record time + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_SPACE; + } + break; + case STATE_SPACE: // timing SPACE + if (irdata == MARK) { // SPACE just ended, record it + irparams.rawbuf[irparams.rawlen++] = irparams.timer; + irparams.timer = 0; + irparams.rcvstate = STATE_MARK; + } + else { // SPACE + if (irparams.timer > GAP_TICKS) { + // big SPACE, indicates gap between codes + // Mark current code as ready for processing + // Switch to STOP + // Don't reset timer; keep counting space width + irparams.rcvstate = STATE_STOP; + } + } + break; + case STATE_STOP: // waiting, measuring gap + if (irdata == MARK) { // reset gap timer + irparams.timer = 0; + } + break; + } + + if (irparams.blinkflag) { + if (irdata == MARK) { + BLINKLED_ON(); // turn pin 13 LED on + } + else { + BLINKLED_OFF(); // turn pin 13 LED off + } + } +} + +void IRrecv::resume() { + irparams.rcvstate = STATE_IDLE; + irparams.rawlen = 0; +} + + + +// Decodes the received IR message +// Returns 0 if no data ready, 1 if data ready. +// Results of decoding are stored in results +int IRrecv::decode(decode_results *results) { + results->rawbuf = irparams.rawbuf; + results->rawlen = irparams.rawlen; + if (irparams.rcvstate != STATE_STOP) { + return ERR; + } +#ifdef DEBUG + Serial.println("Attempting NEC decode"); +#endif + if (decodeNEC(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting Sony decode"); +#endif + if (decodeSony(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting Sanyo decode"); +#endif + if (decodeSanyo(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting Mitsubishi decode"); +#endif + if (decodeMitsubishi(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting RC5 decode"); +#endif + if (decodeRC5(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting RC6 decode"); +#endif + if (decodeRC6(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting Panasonic decode"); +#endif + if (decodePanasonic(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting LG decode"); +#endif + if (decodeLG(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting JVC decode"); +#endif + if (decodeJVC(results)) { + return DECODED; + } +#ifdef DEBUG + Serial.println("Attempting SAMSUNG decode"); +#endif + if (decodeSAMSUNG(results)) { + return DECODED; + } + // decodeHash returns a hash on any input. + // Thus, it needs to be last in the list. + // If you add any decodes, add them before this. + if (decodeHash(results)) { + return DECODED; + } + // Throw away and start over + resume(); + return ERR; +} + +// NECs have a repeat only 4 items long +long IRrecv::decodeNEC(decode_results *results) { + long data = 0; + int offset = 1; // Skip first space + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], NEC_HDR_MARK)) { + return ERR; + } + offset++; + // Check for repeat + if (irparams.rawlen == 4 && + MATCH_SPACE(results->rawbuf[offset], NEC_RPT_SPACE) && + MATCH_MARK(results->rawbuf[offset+1], NEC_BIT_MARK)) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = NEC; + return DECODED; + } + if (irparams.rawlen < 2 * NEC_BITS + 4) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], NEC_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < NEC_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], NEC_BIT_MARK)) { + return ERR; + } + offset++; + if (MATCH_SPACE(results->rawbuf[offset], NEC_ONE_SPACE)) { + data = (data << 1) | 1; + } + else if (MATCH_SPACE(results->rawbuf[offset], NEC_ZERO_SPACE)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + // Success + results->bits = NEC_BITS; + results->value = data; + results->decode_type = NEC; + return DECODED; +} + +long IRrecv::decodeSony(decode_results *results) { + long data = 0; + if (irparams.rawlen < 2 * SONY_BITS + 2) { + return ERR; + } + int offset = 0; // Dont skip first space, check its size + + // Some Sony's deliver repeats fast after first + // unfortunately can't spot difference from of repeat from two fast clicks + if (results->rawbuf[offset] < SONY_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = SANYO; + return DECODED; + } + offset++; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SONY_HDR_MARK)) { + return ERR; + } + offset++; + + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset], SONY_HDR_SPACE)) { + break; + } + offset++; + if (MATCH_MARK(results->rawbuf[offset], SONY_ONE_MARK)) { + data = (data << 1) | 1; + } + else if (MATCH_MARK(results->rawbuf[offset], SONY_ZERO_MARK)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < 12) { + results->bits = 0; + return ERR; + } + results->value = data; + results->decode_type = SONY; + return DECODED; +} + +// I think this is a Sanyo decoder - serial = SA 8650B +// Looks like Sony except for timings, 48 chars of data and time/space different +long IRrecv::decodeSanyo(decode_results *results) { + long data = 0; + if (irparams.rawlen < 2 * SANYO_BITS + 2) { + return ERR; + } + int offset = 0; // Skip first space + // Initial space + /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ + if (results->rawbuf[offset] < SANYO_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = SANYO; + return DECODED; + } + offset++; + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { + return ERR; + } + offset++; + + // Skip Second Mark + if (!MATCH_MARK(results->rawbuf[offset], SANYO_HDR_MARK)) { + return ERR; + } + offset++; + + while (offset + 1 < irparams.rawlen) { + if (!MATCH_SPACE(results->rawbuf[offset], SANYO_HDR_SPACE)) { + break; + } + offset++; + if (MATCH_MARK(results->rawbuf[offset], SANYO_ONE_MARK)) { + data = (data << 1) | 1; + } + else if (MATCH_MARK(results->rawbuf[offset], SANYO_ZERO_MARK)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < 12) { + results->bits = 0; + return ERR; + } + results->value = data; + results->decode_type = SANYO; + return DECODED; +} + +// Looks like Sony except for timings, 48 chars of data and time/space different +long IRrecv::decodeMitsubishi(decode_results *results) { + // Serial.print("?!? decoding Mitsubishi:");Serial.print(irparams.rawlen); Serial.print(" want "); Serial.println( 2 * MITSUBISHI_BITS + 2); + long data = 0; + if (irparams.rawlen < 2 * MITSUBISHI_BITS + 2) { + return ERR; + } + int offset = 0; // Skip first space + // Initial space + /* Put this back in for debugging - note can't use #DEBUG as if Debug on we don't see the repeat cos of the delay + Serial.print("IR Gap: "); + Serial.println( results->rawbuf[offset]); + Serial.println( "test against:"); + Serial.println(results->rawbuf[offset]); + */ + /* Not seeing double keys from Mitsubishi + if (results->rawbuf[offset] < MITSUBISHI_DOUBLE_SPACE_USECS) { + // Serial.print("IR Gap found: "); + results->bits = 0; + results->value = REPEAT; + results->decode_type = MITSUBISHI; + return DECODED; + } + */ + offset++; + + // Typical + // 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 + + // Initial Space + if (!MATCH_MARK(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) { + return ERR; + } + offset++; + while (offset + 1 < irparams.rawlen) { + if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ONE_MARK)) { + data = (data << 1) | 1; + } + else if (MATCH_MARK(results->rawbuf[offset], MITSUBISHI_ZERO_MARK)) { + data <<= 1; + } + else { + // Serial.println("A"); Serial.println(offset); Serial.println(results->rawbuf[offset]); + return ERR; + } + offset++; + if (!MATCH_SPACE(results->rawbuf[offset], MITSUBISHI_HDR_SPACE)) { + // Serial.println("B"); Serial.println(offset); Serial.println(results->rawbuf[offset]); + break; + } + offset++; + } + + // Success + results->bits = (offset - 1) / 2; + if (results->bits < MITSUBISHI_BITS) { + results->bits = 0; + return ERR; + } + results->value = data; + results->decode_type = MITSUBISHI; + return DECODED; +} + + +// Gets one undecoded level at a time from the raw buffer. +// The RC5/6 decoding is easier if the data is broken into time intervals. +// E.g. if the buffer has MARK for 2 time intervals and SPACE for 1, +// successive calls to getRClevel will return MARK, MARK, SPACE. +// offset and used are updated to keep track of the current position. +// t1 is the time interval for a single bit in microseconds. +// Returns -1 for error (measured time interval is not a multiple of t1). +int IRrecv::getRClevel(decode_results *results, int *offset, int *used, int t1) { + if (*offset >= results->rawlen) { + // After end of recorded buffer, assume SPACE. + return SPACE; + } + int width = results->rawbuf[*offset]; + int val = ((*offset) % 2) ? MARK : SPACE; + int correction = (val == MARK) ? MARK_EXCESS : - MARK_EXCESS; + + int avail; + if (MATCH(width, t1 + correction)) { + avail = 1; + } + else if (MATCH(width, 2*t1 + correction)) { + avail = 2; + } + else if (MATCH(width, 3*t1 + correction)) { + avail = 3; + } + else { + return -1; + } + + (*used)++; + if (*used >= avail) { + *used = 0; + (*offset)++; + } +#ifdef DEBUG + if (val == MARK) { + Serial.println("MARK"); + } + else { + Serial.println("SPACE"); + } +#endif + return val; +} + +long IRrecv::decodeRC5(decode_results *results) { + if (irparams.rawlen < MIN_RC5_SAMPLES + 2) { + return ERR; + } + int offset = 1; // Skip gap space + long data = 0; + int used = 0; + // Get start bits + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR; + if (getRClevel(results, &offset, &used, RC5_T1) != SPACE) return ERR; + if (getRClevel(results, &offset, &used, RC5_T1) != MARK) return ERR; + int nbits; + for (nbits = 0; offset < irparams.rawlen; nbits++) { + int levelA = getRClevel(results, &offset, &used, RC5_T1); + int levelB = getRClevel(results, &offset, &used, RC5_T1); + if (levelA == SPACE && levelB == MARK) { + // 1 bit + data = (data << 1) | 1; + } + else if (levelA == MARK && levelB == SPACE) { + // zero bit + data <<= 1; + } + else { + return ERR; + } + } + + // Success + results->bits = nbits; + results->value = data; + results->decode_type = RC5; + return DECODED; +} + +long IRrecv::decodeRC6(decode_results *results) { + if (results->rawlen < MIN_RC6_SAMPLES) { + return ERR; + } + int offset = 1; // Skip first space + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], RC6_HDR_MARK)) { + return ERR; + } + offset++; + if (!MATCH_SPACE(results->rawbuf[offset], RC6_HDR_SPACE)) { + return ERR; + } + offset++; + long data = 0; + int used = 0; + // Get start bit (1) + if (getRClevel(results, &offset, &used, RC6_T1) != MARK) return ERR; + if (getRClevel(results, &offset, &used, RC6_T1) != SPACE) return ERR; + int nbits; + for (nbits = 0; offset < results->rawlen; nbits++) { + int levelA, levelB; // Next two levels + levelA = getRClevel(results, &offset, &used, RC6_T1); + if (nbits == 3) { + // T bit is double wide; make sure second half matches + if (levelA != getRClevel(results, &offset, &used, RC6_T1)) return ERR; + } + levelB = getRClevel(results, &offset, &used, RC6_T1); + if (nbits == 3) { + // T bit is double wide; make sure second half matches + if (levelB != getRClevel(results, &offset, &used, RC6_T1)) return ERR; + } + if (levelA == MARK && levelB == SPACE) { // reversed compared to RC5 + // 1 bit + data = (data << 1) | 1; + } + else if (levelA == SPACE && levelB == MARK) { + // zero bit + data <<= 1; + } + else { + return ERR; // Error + } + } + // Success + results->bits = nbits; + results->value = data; + results->decode_type = RC6; + return DECODED; +} +long IRrecv::decodePanasonic(decode_results *results) { + unsigned long long data = 0; + int offset = 1; + + if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_MARK)) { + return ERR; + } + offset++; + if (!MATCH_MARK(results->rawbuf[offset], PANASONIC_HDR_SPACE)) { + return ERR; + } + offset++; + + // decode address + for (int i = 0; i < PANASONIC_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset++], PANASONIC_BIT_MARK)) { + return ERR; + } + if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ONE_SPACE)) { + data = (data << 1) | 1; + } else if (MATCH_SPACE(results->rawbuf[offset],PANASONIC_ZERO_SPACE)) { + data <<= 1; + } else { + return ERR; + } + offset++; + } + results->value = (unsigned long)data; + results->panasonicAddress = (unsigned int)(data >> 32); + results->decode_type = PANASONIC; + results->bits = PANASONIC_BITS; + return DECODED; +} + +long IRrecv::decodeLG(decode_results *results) { + long data = 0; + int offset = 1; // Skip first space + + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], LG_HDR_MARK)) { + return ERR; + } + offset++; + if (irparams.rawlen < 2 * LG_BITS + 1 ) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], LG_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < LG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)) { + return ERR; + } + offset++; + if (MATCH_SPACE(results->rawbuf[offset], LG_ONE_SPACE)) { + data = (data << 1) | 1; + } + else if (MATCH_SPACE(results->rawbuf[offset], LG_ZERO_SPACE)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + //Stop bit + if (!MATCH_MARK(results->rawbuf[offset], LG_BIT_MARK)){ + return ERR; + } + // Success + results->bits = LG_BITS; + results->value = data; + results->decode_type = LG; + return DECODED; +} + + +long IRrecv::decodeJVC(decode_results *results) { + long data = 0; + int offset = 1; // Skip first space + // Check for repeat + if (irparams.rawlen - 1 == 33 && + MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK) && + MATCH_MARK(results->rawbuf[irparams.rawlen-1], JVC_BIT_MARK)) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = JVC; + return DECODED; + } + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], JVC_HDR_MARK)) { + return ERR; + } + offset++; + if (irparams.rawlen < 2 * JVC_BITS + 1 ) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], JVC_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < JVC_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)) { + return ERR; + } + offset++; + if (MATCH_SPACE(results->rawbuf[offset], JVC_ONE_SPACE)) { + data = (data << 1) | 1; + } + else if (MATCH_SPACE(results->rawbuf[offset], JVC_ZERO_SPACE)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + //Stop bit + if (!MATCH_MARK(results->rawbuf[offset], JVC_BIT_MARK)){ + return ERR; + } + // Success + results->bits = JVC_BITS; + results->value = data; + results->decode_type = JVC; + return DECODED; +} + +// SAMSUNGs have a repeat only 4 items long +long IRrecv::decodeSAMSUNG(decode_results *results) { + long data = 0; + int offset = 1; // Skip first space + // Initial mark + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_HDR_MARK)) { + return ERR; + } + offset++; + // Check for repeat + if (irparams.rawlen == 4 && + MATCH_SPACE(results->rawbuf[offset], SAMSUNG_RPT_SPACE) && + MATCH_MARK(results->rawbuf[offset+1], SAMSUNG_BIT_MARK)) { + results->bits = 0; + results->value = REPEAT; + results->decode_type = SAMSUNG; + return DECODED; + } + if (irparams.rawlen < 2 * SAMSUNG_BITS + 4) { + return ERR; + } + // Initial space + if (!MATCH_SPACE(results->rawbuf[offset], SAMSUNG_HDR_SPACE)) { + return ERR; + } + offset++; + for (int i = 0; i < SAMSUNG_BITS; i++) { + if (!MATCH_MARK(results->rawbuf[offset], SAMSUNG_BIT_MARK)) { + return ERR; + } + offset++; + if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ONE_SPACE)) { + data = (data << 1) | 1; + } + else if (MATCH_SPACE(results->rawbuf[offset], SAMSUNG_ZERO_SPACE)) { + data <<= 1; + } + else { + return ERR; + } + offset++; + } + // Success + results->bits = SAMSUNG_BITS; + results->value = data; + results->decode_type = SAMSUNG; + return DECODED; +} + +/* ----------------------------------------------------------------------- + * hashdecode - decode an arbitrary IR code. + * Instead of decoding using a standard encoding scheme + * (e.g. Sony, NEC, RC5), the code is hashed to a 32-bit value. + * + * The algorithm: look at the sequence of MARK signals, and see if each one + * is shorter (0), the same length (1), or longer (2) than the previous. + * Do the same with the SPACE signals. Hszh the resulting sequence of 0's, + * 1's, and 2's to a 32-bit value. This will give a unique value for each + * different code (probably), for most code systems. + * + * http://arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html + */ + +// Compare two tick values, returning 0 if newval is shorter, +// 1 if newval is equal, and 2 if newval is longer +// Use a tolerance of 20% +int IRrecv::compare(unsigned int oldval, unsigned int newval) { + if (newval < oldval * .8) { + return 0; + } + else if (oldval < newval * .8) { + return 2; + } + else { + return 1; + } +} + +// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param +#define FNV_PRIME_32 16777619 +#define FNV_BASIS_32 2166136261 + +/* Converts the raw code values into a 32-bit hash code. + * Hopefully this code is unique for each button. + * This isn't a "real" decoding, just an arbitrary value. + */ +long IRrecv::decodeHash(decode_results *results) { + // Require at least 6 samples to prevent triggering on noise + if (results->rawlen < 6) { + return ERR; + } + long hash = FNV_BASIS_32; + for (int i = 1; i+2 < results->rawlen; i++) { + int value = compare(results->rawbuf[i], results->rawbuf[i+2]); + // Add value into the hash + hash = (hash * FNV_PRIME_32) ^ value; + } + results->value = hash; + results->bits = 32; + results->decode_type = UNKNOWN; + return DECODED; +} + +/* Sharp and DISH support by Todd Treece ( http://unionbridge.org/design/ircommand ) + +The Dish send function needs to be repeated 4 times, and the Sharp function +has the necessary repeat built in because of the need to invert the signal. + +Sharp protocol documentation: +http://www.sbprojects.com/knowledge/ir/sharp.htm + +Here are the LIRC files that I found that seem to match the remote codes +from the oscilloscope: + +Sharp LCD TV: +http://lirc.sourceforge.net/remotes/sharp/GA538WJSA + +DISH NETWORK (echostar 301): +http://lirc.sourceforge.net/remotes/echostar/301_501_3100_5100_58xx_59xx + +For the DISH codes, only send the last for characters of the hex. +i.e. use 0x1C10 instead of 0x0000000000001C10 which is listed in the +linked LIRC file. +*/ + +void IRsend::sendSharpRaw(unsigned long data, int nbits) { + enableIROut(38); + + // Sending codes in bursts of 3 (normal, inverted, normal) makes transmission + // much more reliable. That's the exact behaviour of CD-S6470 remote control. + for (int n = 0; n < 3; n++) { + for (int i = 1 << (nbits-1); i > 0; i>>=1) { + if (data & i) { + mark(SHARP_BIT_MARK); + space(SHARP_ONE_SPACE); + } + else { + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + } + } + + mark(SHARP_BIT_MARK); + space(SHARP_ZERO_SPACE); + delay(40); + + data = data ^ SHARP_TOGGLE_MASK; + } +} + +// Sharp send compatible with data obtained through decodeSharp +void IRsend::sendSharp(unsigned int address, unsigned int command) { + sendSharpRaw((address << 10) | (command << 2) | 2, 15); +} + +void IRsend::sendDISH(unsigned long data, int nbits) { + enableIROut(56); + mark(DISH_HDR_MARK); + space(DISH_HDR_SPACE); + for (int i = 0; i < nbits; i++) { + if (data & DISH_TOP_BIT) { + mark(DISH_BIT_MARK); + space(DISH_ONE_SPACE); + } + else { + mark(DISH_BIT_MARK); + space(DISH_ZERO_SPACE); + } + data <<= 1; + } +} diff --git a/compilation/arduino/libraries/IRremote/IRremote.h b/compilation/arduino/libraries/IRremote/IRremote.h new file mode 100644 index 00000000..17d5e81b --- /dev/null +++ b/compilation/arduino/libraries/IRremote/IRremote.h @@ -0,0 +1,128 @@ +/* + * IRremote + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.htm http://arcfn.com + * Edited by Mitra to add new controller SANYO + * + * Interrupt code based on NECIRrcv by Joe Knapp + * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 + * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ + * + * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) +* LG added by Darryl Smith (based on the JVC protocol) + */ + +#ifndef IRremote_h +#define IRremote_h + +// The following are compile-time library options. +// If you change them, recompile the library. +// If DEBUG is defined, a lot of debugging output will be printed during decoding. +// TEST must be defined for the IRtest unittests to work. It will make some +// methods virtual, which will be slightly slower, which is why it is optional. +// #define DEBUG +// #define TEST + +// Results returned from the decoder +class decode_results { +public: + int decode_type; // NEC, SONY, RC5, UNKNOWN + union { // This is used for decoding Panasonic and Sharp data + unsigned int panasonicAddress; + unsigned int sharpAddress; + }; + unsigned long value; // Decoded value + int bits; // Number of bits in decoded value + volatile unsigned int *rawbuf; // Raw intervals in .5 us ticks + int rawlen; // Number of records in rawbuf. +}; + +// Values for decode_type +#define NEC 1 +#define SONY 2 +#define RC5 3 +#define RC6 4 +#define DISH 5 +#define SHARP 6 +#define PANASONIC 7 +#define JVC 8 +#define SANYO 9 +#define MITSUBISHI 10 +#define SAMSUNG 11 +#define LG 12 +#define UNKNOWN -1 + +// Decoded value for NEC when a repeat code is received +#define REPEAT 0xffffffff + +// main class for receiving IR +class IRrecv +{ +public: + IRrecv(int recvpin); + void blink13(int blinkflag); + int decode(decode_results *results); + void enableIRIn(); + void resume(); +private: + // These are called by decode + int getRClevel(decode_results *results, int *offset, int *used, int t1); + long decodeNEC(decode_results *results); + long decodeSony(decode_results *results); + long decodeSanyo(decode_results *results); + long decodeMitsubishi(decode_results *results); + long decodeRC5(decode_results *results); + long decodeRC6(decode_results *results); + long decodePanasonic(decode_results *results); + long decodeLG(decode_results *results); + long decodeJVC(decode_results *results); + long decodeSAMSUNG(decode_results *results); + long decodeHash(decode_results *results); + int compare(unsigned int oldval, unsigned int newval); + +} +; + +// Only used for testing; can remove virtual for shorter code +#ifdef TEST +#define VIRTUAL virtual +#else +#define VIRTUAL +#endif + +class IRsend +{ +public: + IRsend() {} + void sendNEC(unsigned long data, int nbits); + void sendSony(unsigned long data, int nbits); + // Neither Sanyo nor Mitsubishi send is implemented yet + // void sendSanyo(unsigned long data, int nbits); + // void sendMitsubishi(unsigned long data, int nbits); + void sendRaw(unsigned int buf[], int len, int hz); + void sendRC5(unsigned long data, int nbits); + void sendRC6(unsigned long data, int nbits); + void sendDISH(unsigned long data, int nbits); + void sendSharp(unsigned int address, unsigned int command); + void sendSharpRaw(unsigned long data, int nbits); + void sendPanasonic(unsigned int address, unsigned long data); + void sendJVC(unsigned long data, int nbits, int repeat); // *Note instead of sending the REPEAT constant if you want the JVC repeat signal sent, send the original code value and change the repeat argument from 0 to 1. JVC protocol repeats by skipping the header NOT by sending a separate code value like NEC does. + // private: + void sendSAMSUNG(unsigned long data, int nbits); + void enableIROut(int khz); + VIRTUAL void mark(int usec); + VIRTUAL void space(int usec); +} +; + +// Some useful constants + +#define USECPERTICK 50 // microseconds per clock interrupt tick +#define RAWBUF 100 // Length of raw duration buffer + +// Marks tend to be 100us too long, and spaces 100us too short +// when received due to sensor lag. +#define MARK_EXCESS 100 + +#endif diff --git a/compilation/arduino/libraries/IRremote/IRremoteInt.h b/compilation/arduino/libraries/IRremote/IRremoteInt.h new file mode 100644 index 00000000..e5653277 --- /dev/null +++ b/compilation/arduino/libraries/IRremote/IRremoteInt.h @@ -0,0 +1,515 @@ +/* + * IRremote + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * For details, see http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html + * + * Modified by Paul Stoffregen to support other boards and timers + * + * Interrupt code based on NECIRrcv by Joe Knapp + * http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1210243556 + * Also influenced by http://zovirl.com/2008/11/12/building-a-universal-remote-with-an-arduino/ + * + * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post) + */ + +#ifndef IRremoteint_h +#define IRremoteint_h + +#if defined(ARDUINO) && ARDUINO >= 100 +#include +#else +#include +#endif + +// define which timer to use +// +// Uncomment the timer you wish to use on your board. If you +// are using another library which uses timer2, you have options +// to switch IRremote to use a different timer. + +// Arduino Mega +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + //#define IR_USE_TIMER1 // tx = pin 11 + #define IR_USE_TIMER2 // tx = pin 9 + //#define IR_USE_TIMER3 // tx = pin 5 + //#define IR_USE_TIMER4 // tx = pin 6 + //#define IR_USE_TIMER5 // tx = pin 46 + +// Teensy 1.0 +#elif defined(__AVR_AT90USB162__) + #define IR_USE_TIMER1 // tx = pin 17 + +// Teensy 2.0 +#elif defined(__AVR_ATmega32U4__) + //#define IR_USE_TIMER1 // tx = pin 14 + //#define IR_USE_TIMER3 // tx = pin 9 + #define IR_USE_TIMER4_HS // tx = pin 10 + +// Teensy 3.0 +#elif defined(__MK20DX128__) + #define IR_USE_TIMER_CMT // tx = pin 5 + +// Teensy++ 1.0 & 2.0 +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) + //#define IR_USE_TIMER1 // tx = pin 25 + #define IR_USE_TIMER2 // tx = pin 1 + //#define IR_USE_TIMER3 // tx = pin 16 + +// Sanguino +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) + //#define IR_USE_TIMER1 // tx = pin 13 + #define IR_USE_TIMER2 // tx = pin 14 + +// Atmega8 +#elif defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) + #define IR_USE_TIMER1 // tx = pin 9 + +// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, etc +#else + //#define IR_USE_TIMER1 // tx = pin 9 + #define IR_USE_TIMER2 // tx = pin 3 +#endif + + + +#ifdef F_CPU +#define SYSCLOCK F_CPU // main Arduino clock +#else +#define SYSCLOCK 16000000 // main Arduino clock +#endif + +#define ERR 0 +#define DECODED 1 + + +// defines for setting and clearing register bits +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +// Pulse parms are *50-100 for the Mark and *50+100 for the space +// First MARK is the one after the long gap +// pulse parameters in usec +#define NEC_HDR_MARK 9000 +#define NEC_HDR_SPACE 4500 +#define NEC_BIT_MARK 560 +#define NEC_ONE_SPACE 1600 +#define NEC_ZERO_SPACE 560 +#define NEC_RPT_SPACE 2250 + +#define SONY_HDR_MARK 2400 +#define SONY_HDR_SPACE 600 +#define SONY_ONE_MARK 1200 +#define SONY_ZERO_MARK 600 +#define SONY_RPT_LENGTH 45000 +#define SONY_DOUBLE_SPACE_USECS 500 // usually ssee 713 - not using ticks as get number wrapround + +// SA 8650B +#define SANYO_HDR_MARK 3500 // seen range 3500 +#define SANYO_HDR_SPACE 950 // seen 950 +#define SANYO_ONE_MARK 2400 // seen 2400 +#define SANYO_ZERO_MARK 700 // seen 700 +#define SANYO_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +#define SANYO_RPT_LENGTH 45000 + +// Mitsubishi RM 75501 +// 14200 7 41 7 42 7 42 7 17 7 17 7 18 7 41 7 18 7 17 7 17 7 18 7 41 8 17 7 17 7 18 7 17 7 + +// #define MITSUBISHI_HDR_MARK 250 // seen range 3500 +#define MITSUBISHI_HDR_SPACE 350 // 7*50+100 +#define MITSUBISHI_ONE_MARK 1950 // 41*50-100 +#define MITSUBISHI_ZERO_MARK 750 // 17*50-100 +// #define MITSUBISHI_DOUBLE_SPACE_USECS 800 // usually ssee 713 - not using ticks as get number wrapround +// #define MITSUBISHI_RPT_LENGTH 45000 + + +#define RC5_T1 889 +#define RC5_RPT_LENGTH 46000 + +#define RC6_HDR_MARK 2666 +#define RC6_HDR_SPACE 889 +#define RC6_T1 444 +#define RC6_RPT_LENGTH 46000 + +#define SHARP_BIT_MARK 245 +#define SHARP_ONE_SPACE 1805 +#define SHARP_ZERO_SPACE 795 +#define SHARP_GAP 600000 +#define SHARP_TOGGLE_MASK 0x3FF +#define SHARP_RPT_SPACE 3000 + +#define DISH_HDR_MARK 400 +#define DISH_HDR_SPACE 6100 +#define DISH_BIT_MARK 400 +#define DISH_ONE_SPACE 1700 +#define DISH_ZERO_SPACE 2800 +#define DISH_RPT_SPACE 6200 +#define DISH_TOP_BIT 0x8000 + +#define PANASONIC_HDR_MARK 3502 +#define PANASONIC_HDR_SPACE 1750 +#define PANASONIC_BIT_MARK 502 +#define PANASONIC_ONE_SPACE 1244 +#define PANASONIC_ZERO_SPACE 400 + +#define JVC_HDR_MARK 8000 +#define JVC_HDR_SPACE 4000 +#define JVC_BIT_MARK 600 +#define JVC_ONE_SPACE 1600 +#define JVC_ZERO_SPACE 550 +#define JVC_RPT_LENGTH 60000 + +#define LG_HDR_MARK 8000 +#define LG_HDR_SPACE 4000 +#define LG_BIT_MARK 600 +#define LG_ONE_SPACE 1600 +#define LG_ZERO_SPACE 550 +#define LG_RPT_LENGTH 60000 + +#define SAMSUNG_HDR_MARK 5000 +#define SAMSUNG_HDR_SPACE 5000 +#define SAMSUNG_BIT_MARK 560 +#define SAMSUNG_ONE_SPACE 1600 +#define SAMSUNG_ZERO_SPACE 560 +#define SAMSUNG_RPT_SPACE 2250 + + +#define SHARP_BITS 15 +#define DISH_BITS 16 + +#define TOLERANCE 25 // percent tolerance in measurements +#define LTOL (1.0 - TOLERANCE/100.) +#define UTOL (1.0 + TOLERANCE/100.) + +#define _GAP 5000 // Minimum map between transmissions +#define GAP_TICKS (_GAP/USECPERTICK) + +#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK)) +#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1)) + +// receiver states +#define STATE_IDLE 2 +#define STATE_MARK 3 +#define STATE_SPACE 4 +#define STATE_STOP 5 + +// information for the interrupt handler +typedef struct { + uint8_t recvpin; // pin for IR data from detector + uint8_t rcvstate; // state machine + uint8_t blinkflag; // TRUE to enable blinking of pin 13 on IR processing + unsigned int timer; // state timer, counts 50uS ticks. + unsigned int rawbuf[RAWBUF]; // raw data + uint8_t rawlen; // counter of entries in rawbuf +} +irparams_t; + +// Defined in IRremote.cpp +extern volatile irparams_t irparams; + +// IR detector output is active low +#define MARK 0 +#define SPACE 1 + +#define TOPBIT 0x80000000 + +#define NEC_BITS 32 +#define SONY_BITS 12 +#define SANYO_BITS 12 +#define MITSUBISHI_BITS 16 +#define MIN_RC5_SAMPLES 11 +#define MIN_RC6_SAMPLES 1 +#define PANASONIC_BITS 48 +#define JVC_BITS 16 +#define LG_BITS 28 +#define SAMSUNG_BITS 32 + + + + +// defines for timer2 (8 bits) +#if defined(IR_USE_TIMER2) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) +#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) +#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) +#define TIMER_DISABLE_INTR (TIMSK2 = 0) +#define TIMER_INTR_NAME TIMER2_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint8_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR2A = _BV(WGM20); \ + TCCR2B = _BV(WGM22) | _BV(CS20); \ + OCR2A = pwmval; \ + OCR2B = pwmval / 3; \ +}) +#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) +#if (TIMER_COUNT_TOP < 256) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS20); \ + OCR2A = TIMER_COUNT_TOP; \ + TCNT2 = 0; \ +}) +#else +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR2A = _BV(WGM21); \ + TCCR2B = _BV(CS21); \ + OCR2A = TIMER_COUNT_TOP / 8; \ + TCNT2 = 0; \ +}) +#endif +#if defined(CORE_OC2B_PIN) +#define TIMER_PWM_PIN CORE_OC2B_PIN /* Teensy */ +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define TIMER_PWM_PIN 9 /* Arduino Mega */ +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +#define TIMER_PWM_PIN 14 /* Sanguino */ +#else +#define TIMER_PWM_PIN 3 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ +#endif + + +// defines for timer1 (16 bits) +#elif defined(IR_USE_TIMER1) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR1A |= _BV(COM1A1)) +#define TIMER_DISABLE_PWM (TCCR1A &= ~(_BV(COM1A1))) +#if defined(__AVR_ATmega8P__) || defined(__AVR_ATmega8__) + #define TIMER_ENABLE_INTR (TIMSK = _BV(OCIE1A)) + #define TIMER_DISABLE_INTR (TIMSK = 0) +#else + #define TIMER_ENABLE_INTR (TIMSK1 = _BV(OCIE1A)) + #define TIMER_DISABLE_INTR (TIMSK1 = 0) +#endif +#define TIMER_INTR_NAME TIMER1_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR1A = _BV(WGM11); \ + TCCR1B = _BV(WGM13) | _BV(CS10); \ + ICR1 = pwmval; \ + OCR1A = pwmval / 3; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR1A = 0; \ + TCCR1B = _BV(WGM12) | _BV(CS10); \ + OCR1A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT1 = 0; \ +}) +#if defined(CORE_OC1A_PIN) +#define TIMER_PWM_PIN CORE_OC1A_PIN /* Teensy */ +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define TIMER_PWM_PIN 11 /* Arduino Mega */ +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +#define TIMER_PWM_PIN 13 /* Sanguino */ +#else +#define TIMER_PWM_PIN 9 /* Arduino Duemilanove, Diecimila, LilyPad, etc */ +#endif + + +// defines for timer3 (16 bits) +#elif defined(IR_USE_TIMER3) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR3A |= _BV(COM3A1)) +#define TIMER_DISABLE_PWM (TCCR3A &= ~(_BV(COM3A1))) +#define TIMER_ENABLE_INTR (TIMSK3 = _BV(OCIE3A)) +#define TIMER_DISABLE_INTR (TIMSK3 = 0) +#define TIMER_INTR_NAME TIMER3_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR3A = _BV(WGM31); \ + TCCR3B = _BV(WGM33) | _BV(CS30); \ + ICR3 = pwmval; \ + OCR3A = pwmval / 3; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR3A = 0; \ + TCCR3B = _BV(WGM32) | _BV(CS30); \ + OCR3A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT3 = 0; \ +}) +#if defined(CORE_OC3A_PIN) +#define TIMER_PWM_PIN CORE_OC3A_PIN /* Teensy */ +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define TIMER_PWM_PIN 5 /* Arduino Mega */ +#else +#error "Please add OC3A pin number here\n" +#endif + + +// defines for timer4 (10 bits, high speed option) +#elif defined(IR_USE_TIMER4_HS) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(TOIE4)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_OVF_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = (1<> 8; \ + OCR4C = pwmval; \ + TC4H = (pwmval / 3) >> 8; \ + OCR4A = (pwmval / 3) & 255; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(CS40); \ + TCCR4C = 0; \ + TCCR4D = 0; \ + TCCR4E = 0; \ + TC4H = (SYSCLOCK * USECPERTICK / 1000000) >> 8; \ + OCR4C = (SYSCLOCK * USECPERTICK / 1000000) & 255; \ + TC4H = 0; \ + TCNT4 = 0; \ +}) +#if defined(CORE_OC4A_PIN) +#define TIMER_PWM_PIN CORE_OC4A_PIN /* Teensy */ +#elif defined(__AVR_ATmega32U4__) +#define TIMER_PWM_PIN 13 /* Leonardo */ +#else +#error "Please add OC4A pin number here\n" +#endif + + +// defines for timer4 (16 bits) +#elif defined(IR_USE_TIMER4) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR4A |= _BV(COM4A1)) +#define TIMER_DISABLE_PWM (TCCR4A &= ~(_BV(COM4A1))) +#define TIMER_ENABLE_INTR (TIMSK4 = _BV(OCIE4A)) +#define TIMER_DISABLE_INTR (TIMSK4 = 0) +#define TIMER_INTR_NAME TIMER4_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR4A = _BV(WGM41); \ + TCCR4B = _BV(WGM43) | _BV(CS40); \ + ICR4 = pwmval; \ + OCR4A = pwmval / 3; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR4A = 0; \ + TCCR4B = _BV(WGM42) | _BV(CS40); \ + OCR4A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT4 = 0; \ +}) +#if defined(CORE_OC4A_PIN) +#define TIMER_PWM_PIN CORE_OC4A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define TIMER_PWM_PIN 6 /* Arduino Mega */ +#else +#error "Please add OC4A pin number here\n" +#endif + + +// defines for timer5 (16 bits) +#elif defined(IR_USE_TIMER5) +#define TIMER_RESET +#define TIMER_ENABLE_PWM (TCCR5A |= _BV(COM5A1)) +#define TIMER_DISABLE_PWM (TCCR5A &= ~(_BV(COM5A1))) +#define TIMER_ENABLE_INTR (TIMSK5 = _BV(OCIE5A)) +#define TIMER_DISABLE_INTR (TIMSK5 = 0) +#define TIMER_INTR_NAME TIMER5_COMPA_vect +#define TIMER_CONFIG_KHZ(val) ({ \ + const uint16_t pwmval = SYSCLOCK / 2000 / (val); \ + TCCR5A = _BV(WGM51); \ + TCCR5B = _BV(WGM53) | _BV(CS50); \ + ICR5 = pwmval; \ + OCR5A = pwmval / 3; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + TCCR5A = 0; \ + TCCR5B = _BV(WGM52) | _BV(CS50); \ + OCR5A = SYSCLOCK * USECPERTICK / 1000000; \ + TCNT5 = 0; \ +}) +#if defined(CORE_OC5A_PIN) +#define TIMER_PWM_PIN CORE_OC5A_PIN +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define TIMER_PWM_PIN 46 /* Arduino Mega */ +#else +#error "Please add OC5A pin number here\n" +#endif + + +// defines for special carrier modulator timer +#elif defined(IR_USE_TIMER_CMT) +#define TIMER_RESET ({ \ + uint8_t tmp = CMT_MSC; \ + CMT_CMD2 = 30; \ +}) +#define TIMER_ENABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(2)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_DISABLE_PWM CORE_PIN5_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE +#define TIMER_ENABLE_INTR NVIC_ENABLE_IRQ(IRQ_CMT) +#define TIMER_DISABLE_INTR NVIC_DISABLE_IRQ(IRQ_CMT) +#define TIMER_INTR_NAME cmt_isr +#ifdef ISR +#undef ISR +#endif +#define ISR(f) void f(void) +#if F_BUS == 48000000 +#define CMT_PPS_VAL 5 +#else +#define CMT_PPS_VAL 2 +#endif +#define TIMER_CONFIG_KHZ(val) ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + SIM_SOPT2 |= SIM_SOPT2_PTD7PAD; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 2667 / val; \ + CMT_CGL1 = 5333 / val; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 0; \ + CMT_OC = 0x60; \ + CMT_MSC = 0x01; \ +}) +#define TIMER_CONFIG_NORMAL() ({ \ + SIM_SCGC4 |= SIM_SCGC4_CMT; \ + CMT_PPS = CMT_PPS_VAL; \ + CMT_CGH1 = 1; \ + CMT_CGL1 = 1; \ + CMT_CMD1 = 0; \ + CMT_CMD2 = 30; \ + CMT_CMD3 = 0; \ + CMT_CMD4 = 19; \ + CMT_OC = 0; \ + CMT_MSC = 0x03; \ +}) +#define TIMER_PWM_PIN 5 + + +#else // unknown timer +#error "Internal code configuration error, no known IR_USE_TIMER# defined\n" +#endif + + +// defines for blinking the LED +#if defined(CORE_LED0_PIN) +#define BLINKLED CORE_LED0_PIN +#define BLINKLED_ON() (digitalWrite(CORE_LED0_PIN, HIGH)) +#define BLINKLED_OFF() (digitalWrite(CORE_LED0_PIN, LOW)) +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define BLINKLED 13 +#define BLINKLED_ON() (PORTB |= B10000000) +#define BLINKLED_OFF() (PORTB &= B01111111) +#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) +#define BLINKLED 0 +#define BLINKLED_ON() (PORTD |= B00000001) +#define BLINKLED_OFF() (PORTD &= B11111110) +#else +#define BLINKLED 13 +#define BLINKLED_ON() (PORTB |= B00100000) +#define BLINKLED_OFF() (PORTB &= B11011111) +#endif + +#endif diff --git a/compilation/arduino/libraries/extension/extension.cpp b/compilation/arduino/libraries/extension/extension.cpp index ef7535be..ec3b9349 100644 --- a/compilation/arduino/libraries/extension/extension.cpp +++ b/compilation/arduino/libraries/extension/extension.cpp @@ -1,9 +1,9 @@ #include #include "extension.h" -extension::extension(){} +Extension::Extension(){} -void extension::ultrason(byte trig, byte echo){ +void Extension::ultrason(byte trig, byte echo){ pinMode(trig, OUTPUT); digitalWrite(trig, LOW); pinMode(echo, INPUT); @@ -11,117 +11,55 @@ void extension::ultrason(byte trig, byte echo){ echo_pin = echo; } -float extension::ultrason_distance(){ +float Extension::mesure_distance(){ digitalWrite(trig_pin, HIGH); delayMicroseconds(10); digitalWrite(trig_pin, LOW); return pulseIn(echo_pin, HIGH)/58; } -void extension::bargraphe(byte dcki, byte di){ +void Extension::bargraphe(byte dcki, byte di){ pinMode(dcki, OUTPUT); pinMode(di, OUTPUT); dcki_pin = dcki; di_pin = di; } -void extension::bargraphe_allumer(byte del){ - unsigned char _state[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; - void sendData(unsigned int data) { - for (unsigned char i=0; i < 16; i++){ - unsigned int state=(data&0x8000) ? HIGH : LOW; - digitalWrite(di_pin, state); - state=digitalRead(dcki_pin) ? LOW : HIGH; - digitalWrite(dcki_pin, state); - data <<= 1; - } - } - void setData(unsigned char _state[]) { - sendData(0x00); - for (unsigned char i=0; i<10; i++) sendData(_state[10-i-1]); - sendData(0x00); - sendData(0x00); - digitalWrite(di_pin, LOW); - delayMicroseconds(10); - for (unsigned char i=0; i<4; i++){ +void Extension::sendData(unsigned int data){ + for (byte i=0; i < 16; i++){ + unsigned int state=(data&0x8000) ? HIGH : LOW; + digitalWrite(di_pin, state); + state=digitalRead(dcki_pin) ? LOW : HIGH; + digitalWrite(dcki_pin, state); + data <<= 1; + } +} + +void Extension::setData(unsigned char _state[]){ + sendData(0x00); + for (byte i=0; i<10; i++) sendData(_state[10-i-1]); + sendData(0x00); + sendData(0x00); + digitalWrite(di_pin, LOW); + delayMicroseconds(10); + for (byte i=0; i<4; i++){ digitalWrite(di_pin, HIGH); digitalWrite(di_pin, LOW); - } } +} + +void Extension::bargraphe_allumer(float del){ + unsigned char _state[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; del=max(0, min(10, del)); del *= 8; for (byte i=0; i<10; i++) { _state[i]=(del>8) ? ~0 : (del>0) ? ~(~0 << byte(del)) : 0; del -= 8; - }; - setData(_state); -} - -void extension::matrice16(){ - pinMode(A4,OUTPUT); - pinMode(A5,OUTPUT); - digitalWrite(A4,LOW); - digitalWrite(A5,LOW); - sda_pin = A4; - scl_pin = A5; -} - -void extension::matrice16_afficher(byte s[]){ - void IIC_start() { - digitalWrite(scl_pin,LOW); - delayMicroseconds(3); - digitalWrite(sda_pin,HIGH); - delayMicroseconds(3); - digitalWrite(scl_pin,HIGH); - delayMicroseconds(3); - digitalWrite(sda_pin,LOW); - delayMicroseconds(3); - } - void IIC_end() { - digitalWrite(scl_pin,LOW); - delayMicroseconds(3); - digitalWrite(sda_pin,LOW); - delayMicroseconds(3); - digitalWrite(scl_pin,HIGH); - delayMicroseconds(3); - digitalWrite(sda_pin,HIGH); - delayMicroseconds(3); - } - void IIC_send(unsigned char send_data) { - for(char i = 0;i < 8;i++) { - digitalWrite(scl_pin,LOW); - delayMicroseconds(3); - if(send_data & 0x01) { - digitalWrite(sda_pin,HIGH); - } else { - digitalWrite(sda_pin,LOW); - } - delayMicroseconds(3); - digitalWrite(scl_pin,HIGH); - delayMicroseconds(3); - send_data = send_data >> 1; - } } - IIC_start(); - IIC_send(0x40); - IIC_end(); - IIC_start(); - IIC_send(0xC0); - for(char i=0; i<16; i++) { - IIC_send(s[i]); - } - IIC_end(); - IIC_start(); - IIC_send(0x8F); - IIC_end(); -} - -void extension::matrice16_effacer(){ - byte t[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - matrice16_afficher (t); + setData(_state); } -void extension::rvb(byte pinR, byte pinV, byte pinB){ +void Extension::rvb(byte pinR, byte pinV, byte pinB){ pinMode(pinR, OUTPUT); pinMode(pinV, OUTPUT); pinMode(pinB, OUTPUT); @@ -130,12 +68,64 @@ void extension::rvb(byte pinR, byte pinV, byte pinB){ Bleu_pin = pinB; } -void extension::rvb_afficher_couleur(byte red, byte green, byte blue){ +void Extension::rvb_afficher_couleur(byte red, byte green, byte blue){ analogWrite(Rouge_pin, red); analogWrite(Vert_pin, green); analogWrite(Bleu_pin, blue); } -void extension::mp3(){ - -} \ No newline at end of file +void Extension::exe_cmd(byte CMD, byte Par1, byte Par2){ + word check=-(0xFF + 0x06 + CMD + 0x00 + Par1 + Par2); + byte Command[10]={0x7E,0xFF,0x06,CMD,0x00,Par1,Par2,highByte(check),lowByte(check),0xEF}; + for (byte i=0; i<10; i++) Serial.write(Command[i]); +} + +void Extension::mp3(byte volume_hex){ + Serial.begin(9600); + delay(1000); + exe_cmd(0x3F,0,0); + delay(500); + exe_cmd(0x06,0,volume_hex); + delay(500); +} + +void Extension::mp3_lecture_auto(byte volume_hex){ + Serial.begin(9600); + delay(1000); + exe_cmd(0x3F,0,0); + delay(500); + exe_cmd(0x06,0,volume_hex); + delay(500); + exe_cmd(0x11,0,1); + delay(500); +} + +void Extension::mp3_lecture(){ + exe_cmd(0x0D,0,1); + delay(500); +} + +void Extension::mp3_pause(){ + exe_cmd(0x0E,0,0); + delay(500); +} + +void Extension::mp3_suivant(){ + exe_cmd(0x01,0,1); + delay(500); +} + +void Extension::mp3_precedent(){ + exe_cmd(0x02,0,1); + delay(500); +} + +void Extension::mp3_volume(byte volume_hex){ + exe_cmd(0x06,0,volume_hex); + delay(500); +} + +void Extension::mp3_lecture_piste(byte piste){ + exe_cmd(0x03,0,piste); + delay(500); +} diff --git a/compilation/arduino/libraries/extension/extension.h b/compilation/arduino/libraries/extension/extension.h index 18f091fd..f984c1ec 100644 --- a/compilation/arduino/libraries/extension/extension.h +++ b/compilation/arduino/libraries/extension/extension.h @@ -1,18 +1,23 @@ #ifndef extension_h #define extension_h -class extension { +class Extension { public: - extension(); + Extension(); void ultrason(byte trig, byte echo); - float ultrason_distance(); + float mesure_distance(); void bargraphe(byte dcki, byte di); - void bargraphe_allumer(byte del); - void matrice16(byte sda, byte scl); - void matrice32(byte sda, byte scl); + void bargraphe_allumer(float del); void rvb(byte pinR, byte pinV, byte pinB); void rvb_afficher_couleur(byte red, byte green, byte blue); - void mp3(); + void mp3(byte volume_hex); + void mp3_lecture_auto(byte volume_hex); + void mp3_lecture(); + void mp3_lecture_piste(byte piste); + void mp3_suivant(); + void mp3_precedent(); + void mp3_pause(); + void mp3_volume(byte volume_hex); private: byte Rouge_pin; byte Vert_pin; @@ -21,8 +26,9 @@ class extension { byte echo_pin; byte dcki_pin; byte di_pin; - byte sda_pin; - byte scl_pin; + void setData(unsigned char _state[]); + void sendData(unsigned int data); + void exe_cmd(byte CMD, byte Par1, byte Par2); }; #endif \ No newline at end of file diff --git a/package.json b/package.json index d1ec3d76..2dd8c094 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "Blocklino", - "version": "1.8.0", + "version": "1.9.0", "description": "environnement de développement pour langage graphique", "author": "Fontaine Jean Philippe", "license": "CC0-1.0", + "homepage": "https://fontainejp.github.io/", "main": "electronApp.js", "keywords": [ "blockly", @@ -31,7 +32,9 @@ "postinstall": "electron-builder install-app-deps", "start": "electron .", "compiler": "build --win --ia32", - "publier": "build --win --ia32 -p always" + "publier": "build --win --ia32 -p always", + "comp-mac": "build --mac", + "pub-mac": "build --mac -p always" }, "build": { "appId": "com.electron.blocklino", @@ -58,6 +61,10 @@ ], "icon": "build/app.ico" }, + "mac": { + "target": "dmg", + "icon": "build/app.icns" + }, "fileAssociations": [ { "ext": "bloc", diff --git a/www/accueil.html b/www/accueil.html deleted file mode 100644 index 7b3060b4..00000000 --- a/www/accueil.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - BLOCKLY-TOOLS - - - - - - - - - -
-
- -
-
-
-
-
-

BLOCKLY-TOOLS

-

environnement de développement pour langage graphique libre et open source.

-


-
-
- -

BLOCKLINO

- Programmation de carte à microcontrôlleur.

- Démarrer -
-
-
-

BLOCKLY-WEB

- Le HTML et CSS en temps réel.


- Démarrer -
-
- -

BLOCKLY-FACTORY

- Fabriquer vos propres blocs.


- Démarrer -
-
-
-
-
- - - \ No newline at end of file diff --git a/www/blocs&generateurs/_actionneur.js b/www/blocs&generateurs/_actionneur.js index 143fa7bb..b8acd749 100644 --- a/www/blocs&generateurs/_actionneur.js +++ b/www/blocs&generateurs/_actionneur.js @@ -730,7 +730,7 @@ Blockly.Arduino["pixel_setcolor"]=function(block){ var color=block.getFieldValue("color"); var colorR=color[1] + color[2], colorG=color[3] + color[4], colorB=color[5] + color[6]; var red=parseInt(colorR,16), green=parseInt(colorG,16), blue=parseInt(colorB,16); - return "pixel.setPixelColor(" + pin + ", " + red + ", " + green + ", " + blue + ");\n" + return "pixel.setPixelColor(" + pin + ", " + red + ", " + green + ", " + blue + ");\npixel.show();\n" }; Blockly.Python["pixel_setcolor"]=function(block){ var pin=Blockly.Python.valueToCode(block, "broche", Blockly.Python.ORDER_ASSIGNMENT); @@ -771,7 +771,7 @@ Blockly.Blocks["pixel_clear"]={init:function(){ this.setHelpUrl("http://")} }; Blockly.Arduino["pixel_clear"]=function(block){ - return "pixel.show();\n" + return "pixel.clear();\npixel.show();\n" }; Blockly.Python["pixel_clear"]=function(block){ var carte = localStorage.getItem('card') @@ -781,7 +781,6 @@ Blockly.Python["pixel_clear"]=function(block){ } else { return "np.clear()\n" } - }; ////////////// Blockly.Blocks["pixel_setbrightness"]={init:function(){ @@ -797,6 +796,25 @@ Blockly.Arduino["pixel_setbrightness"]=function(block){ return "pixel.setBrightness(" + value + ");\n" }; Blockly.Python["pixel_setbrightness"]=function(){return""}; +////////////// +Blockly.Blocks["pixel_setcolor_random"]={init:function(){ + this.appendValueInput("broche").setCheck("Number").appendField(Blockly.Msg.pixel6); + this.appendDummyInput().appendField(Blockly.Msg.pixel8); + this.setInputsInline(true); + this.setPreviousStatement(true, null); + this.setNextStatement(true, null); + this.setColour("#00929F"); + this.setTooltip(Blockly.Msg.pixel6_tooltip); + this.setHelpUrl("http://")} +}; +Blockly.Arduino["pixel_setcolor_random"]=function(block){ + var pin=Blockly.Arduino.valueToCode(block, "broche", Blockly.Arduino.ORDER_ASSIGNMENT); + Blockly.Arduino.setups_["randomSeed"]="randomSeed(analogRead(0));"; + return "pixel.setPixelColor(" + pin + ", random(0,256), random(0,256), random(0,256));\npixel.show();\n" +}; +Blockly.Python["pixel_setcolor_random"]=function(block){ + return "" +}; ////////////// /* moteur */ ////////////// diff --git a/www/blocs&generateurs/_microbit.js b/www/blocs&generateurs/_microbit.js index d68af558..04ec869d 100644 --- a/www/blocs&generateurs/_microbit.js +++ b/www/blocs&generateurs/_microbit.js @@ -554,7 +554,7 @@ Blockly.Blocks["plays"]={init:function(){ Blockly.Python["plays"]=function(block){ var value_note=block.getFieldValue("note"); var value_tempo=block.getFieldValue("tempo"); - Blockly.Python.imports_["time"]="import time"; + Blockly.Python.imports_["music"]="import music"; return 'music.play(["' + value_note + ':' + value_tempo +'"])\n' }; ////////////// @@ -873,7 +873,7 @@ Blockly.Arduino['print'] = function(block) { return "Serial.println(" + str + ");\n" }; ///////////////// -/* bluetooth */ +/* bluetooth /////////////// Blockly.Blocks["bluetooth_a"]={init:function(){ this.appendValueInput("data_s").setCheck("Number").appendField(Blockly.Msg.bluetooth2); @@ -1036,4 +1036,5 @@ Blockly.Blocks["bluetooth_create_container"]={init:function(){ this.contextMenu = false } }; -////////////// \ No newline at end of file +////////////// +*/ \ No newline at end of file diff --git a/www/blocs&generateurs/arduino_generateurs_cpp.js b/www/blocs&generateurs/arduino_generateurs_cpp.js index 1e7d779b..04862987 100644 --- a/www/blocs&generateurs/arduino_generateurs_cpp.js +++ b/www/blocs&generateurs/arduino_generateurs_cpp.js @@ -131,7 +131,7 @@ Blockly.Arduino["bluetooth_init"]=function(block){ var dropdown_pin2=Blockly.Arduino.valueToCode(block,"PIN2", Blockly.Arduino.ORDER_NONE); var dropdown_speed=block.getFieldValue("SPEED"); var n=0; - Blockly.Arduino.includes_["bluetooth"]="#include "; + Blockly.Arduino.includes_["define_ss"]="#include "; Blockly.Arduino.definitions_["bluetooth"]="SoftwareSerial bluetooth("+dropdown_pin1+","+dropdown_pin2+");"; Blockly.Arduino.setups_["bluetooth"]="bluetooth.begin(" + dropdown_speed + ");"; return "" diff --git a/www/blocs&generateurs/factory/add.js b/www/blocs&generateurs/factory/add.js deleted file mode 100644 index 811bd888..00000000 --- a/www/blocs&generateurs/factory/add.js +++ /dev/null @@ -1,13 +0,0 @@ -Blockly.Blocks['monbloc']={init:function(){ - this.appendDummyInput() - .setAlign(Blockly.ALIGN_CENTRE) - .appendField("code()"); - this.setInputsInline(false); - this.setOutput(true); - this.setColour('#00929f')} -}; -Blockly.Python['monbloc']=function(block){ - Blockly.Python.userFunctions_['func'] = 'def code():\n return 0'; - var code = 'code()'; - return [code, Blockly.Python.ORDER_ATOMIC]; -}; \ No newline at end of file diff --git a/www/blocs&generateurs/factory/append.js b/www/blocs&generateurs/factory/append.js index bd144996..35ce40f3 100644 --- a/www/blocs&generateurs/factory/append.js +++ b/www/blocs&generateurs/factory/append.js @@ -1 +1,2 @@ // Blocs réalisés avec BLOCKLY-FACTORY + diff --git a/www/blocs&generateurs/factory/generator.js b/www/blocs&generateurs/factory/generator.js index 836a8f36..d22f88c9 100644 --- a/www/blocs&generateurs/factory/generator.js +++ b/www/blocs&generateurs/factory/generator.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict'; var blockType = ''; var mainWorkspace = null; @@ -250,14 +250,14 @@ function updateGenerator() { } } if (language_generator=="Arduino") { - code.push(" Blockly." + language_generator + ".includes_['lib'] = '#include <lib.h> ;';"); - code.push(" Blockly." + language_generator + ".variables_['var'] = 'int var;';"); - code.push(" Blockly." + language_generator + ".definitions_['inst'] = 'inst instance;';"); - code.push(" Blockly." + language_generator + ".userFunctions_['func'] = 'void func(){return 0};';"); - code.push(" Blockly." + language_generator + ".setups_['setup'] = 'code du setup();';"); - code.push(" var code = 'code du loop()';"); + code.push(" Blockly." + language_generator + ".includes_['lib'] = '#include \"lib.h\" ;'; // à supprimer si inutile"); + code.push(" Blockly." + language_generator + ".variables_['var'] = 'int var;'; // à supprimer si inutile"); + code.push(" Blockly." + language_generator + ".definitions_['inst'] = 'inst instance;'; // à supprimer si inutile"); + code.push(" Blockly." + language_generator + ".userFunctions_['func'] = 'void func(){return 0};'; // à supprimer si inutile"); + code.push(" Blockly." + language_generator + ".setups_['setup'] = 'code_setup();'; // à supprimer si inutile"); + code.push(" var code = 'code_loop();\\n';"); if (rootBlock.getFieldValue('CONNECTIONS') == 'LEFT') { - code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC];"); + code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC]"); } else { code.push(" return code"); } @@ -266,9 +266,9 @@ function updateGenerator() { code.push(" Blockly." + language_generator + ".imports_['lib'] = 'import lib';"); code.push(" Blockly." + language_generator + ".definitions_['inst'] = 'inst instance';"); code.push(" Blockly." + language_generator + ".userFunctions_['func'] = 'def func():\\n return 0';"); - code.push(" var code = 'placer ici le reste du code';"); + code.push(" var code = 'code';"); if (rootBlock.getFieldValue('CONNECTIONS') == 'LEFT') { - code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC];"); + code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC]"); } else { code.push(" return code"); } @@ -276,7 +276,7 @@ function updateGenerator() { if (language_generator=="html") { code.push(" var code = 'placer votre code ici'"); if (rootBlock.getFieldValue('CONNECTIONS') == 'LEFT') { - code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC];"); + code.push(" return [code, Blockly." + language_generator + ".ORDER_ATOMIC]"); } else { code.push(" return code"); } @@ -285,9 +285,17 @@ function updateGenerator() { code.push("};"); editor.setValue(code.join('\n'),1); } +var oldDir = null; function updatePreview() { - if (previewWorkspace) previewWorkspace.dispose(); - previewWorkspace = Blockly.inject('preview',{scrollbars:true,grid:{snap:true},media:'media/',sounds:false,zoom:{controls:true,wheel:true}}); + var newDir = document.getElementById('direction').value; + if (oldDir != newDir) { + if (previewWorkspace) { + previewWorkspace.dispose(); + } + var rtl = newDir == 'rtl'; + previewWorkspace = Blockly.inject('preview',{rtl: rtl, media: 'media/', sounds: false, scrollbars: true}); + oldDir = newDir; + } previewWorkspace.clear(); if (Blockly.Blocks[blockType]) throw 'Block name collides with existing property: ' + blockType; var code = document.getElementById('languagePre').textContent.trim(); @@ -342,22 +350,9 @@ function init() { rootBlock.initSvg(); rootBlock.render(); rootBlock.setDeletable(false); - /*var urlFile = getStringParamFromUrl('url', '') - if (urlFile) { - $.get( urlFile, function(data){ - if (data){ - var xml = Blockly.Xml.textToDom(data); - mainWorkspace.clear(); - Blockly.Xml.domToWorkspace(xml, mainWorkspace); - mainWorkspace.render(); - var elem = xml.getElementsByTagName("language")[0]; - var node = elem.childNodes[0]; - localStorage.code_bf = node.nodeValue; - } - }, 'text') - }*/ mainWorkspace.addChangeListener(onchange); if (window.localStorage.prog == "python") $("#language_generator").val("Python"); + document.getElementById('direction').addEventListener('change', updatePreview); document.getElementById('language_generator').addEventListener('change', updateGenerator); $('[data-toggle="tooltip"]').tooltip(); } diff --git a/www/factory.html b/www/factory.html index 2b981a29..8556fa91 100644 --- a/www/factory.html +++ b/www/factory.html @@ -64,6 +64,10 @@
+
Prévisualisation :
diff --git a/www/index.html b/www/index.html index 1a44fdfb..d02654f9 100644 --- a/www/index.html +++ b/www/index.html @@ -519,39 +519,66 @@
diff --git a/www/js/blocklino.js b/www/js/blocklino.js index 82c75e2c..9d60b6a1 100644 --- a/www/js/blocklino.js +++ b/www/js/blocklino.js @@ -1,11 +1,13 @@ 'use strict'; var BlocklyDuino = {}; +var option_scratch = {}; BlocklyDuino.selectedToolbox = "toolbox_arduino_all"; BlocklyDuino.selectedCard = "uno"; BlocklyDuino.content = "on"; BlocklyDuino.contentHTML = "on"; BlocklyDuino.theme = "sqlserver"; +BlocklyDuino.renderer = "blockly"; BlocklyDuino.size = "14px"; BlocklyDuino.workspace = null; BlocklyDuino.loadOnce = ""; @@ -16,7 +18,11 @@ BlocklyDuino.prog_microbit = "# Python\n\nfrom microbit import *\n\nwhile True:\ BlocklyDuino.init = function() { Code.initLanguage(); BlocklyDuino.loadConfig(); - BlocklyDuino.workspace = Blockly.inject('content_blocks',{grid:{snap:true},sounds:false,media:'media/',toolbox:BlocklyDuino.buildToolbox(),zoom:{controls:true,wheel:true}}); + if (window.localStorage.renderer == "blockly") { + BlocklyDuino.workspace = Blockly.inject('content_blocks',{grid:{snap:true},sounds:false,media:'media/',toolbox:BlocklyDuino.buildToolbox(),zoom:{controls:true,wheel:true}}); + } else { + BlocklyDuino.workspace = Blockly.inject('content_blocks',option_scratch); + } var bTD = document.getElementsByClassName('blocklyToolboxDiv'); if ($("#toolboxes").val()=="toolbox_fresnel_all") { bTD[0].style.width = "290px" @@ -151,6 +157,7 @@ BlocklyDuino.loadConfig = function() { var content = window.localStorage.content; var prog = window.localStorage.prog; var theme = window.localStorage.theme; + var renderer = window.localStorage.renderer; var size = window.localStorage.size; if (card===undefined) { window.localStorage.card = BlocklyDuino.selectedCard; @@ -200,6 +207,9 @@ BlocklyDuino.loadConfig = function() { $('#fontsize').val(size); document.getElementById('content_code').style.fontSize = size } + if (renderer === undefined) { + window.localStorage.renderer = BlocklyDuino.renderer + } } BlocklyDuino.change_card = function() { //BlocklyDuino.backupBlocks(); @@ -322,6 +332,7 @@ BlocklyDuino.bindFunctions = function() { window.localStorage.size = $(this).val() }); $('#theme').on("change", BlocklyDuino.apply_theme); + $('#renderer').on("change", BlocklyDuino.apply_renderer); $('.modal-child').on('show.bs.modal', function () { var modalParent = $(this).attr('data-modal-parent'); $(modalParent).css('opacity', 0) @@ -459,6 +470,15 @@ BlocklyDuino.apply_theme = function () { BlocklyDuino.theme_sqlserver() } } +BlocklyDuino.apply_renderer = function () { + var new_renderer = $('#renderer').val(); + window.localStorage.renderer = new_renderer + if (new_renderer == "blockly") { + + } else { + + } +} BlocklyDuino.checkAll = function () { if(this.checked) { $('#modal-body-config input:checkbox[id^=checkbox_]').each(function() { diff --git a/www/lang/Arduino_en.js b/www/lang/Arduino_en.js index 6ccdbdb4..307cbbd9 100644 --- a/www/lang/Arduino_en.js +++ b/www/lang/Arduino_en.js @@ -215,11 +215,13 @@ Blockly.Msg.pixel4 = "number"; Blockly.Msg.pixel5 = "set pixel brightness to"; Blockly.Msg.pixel6 = "set the pixel"; Blockly.Msg.pixel7 = "turn off pixels"; +Blockly.Msg.pixel8="with random color"; Blockly.Msg.pixel1_tooltip="neopixel RGB module indicate the pin to be connected and the number of pixels"; Blockly.Msg.pixel2_tooltip="show changes made"; Blockly.Msg.pixel3_tooltip="choose the pixel to light and its color \nCaution the numbering starts at 0"; Blockly.Msg.pixel4_tooltip="turn off all the pixels"; Blockly.Msg.pixel5_tooltip="adjusts pixel brightness (from 0 to 255)"; +Blockly.Msg.pixel6_tooltip="choose the pixel to light and its random color\nCaution the numbering starts at 0"; // output Blockly.Msg.ARDUINO_INOUT_DIGITAL_WRITE_INPUT1 = "put the DIGITAL pin"; Blockly.Msg.ARDUINO_INOUT_DIGITAL_WRITE_TOOLTIP = "write a 0 or 1 logical state to a specific output"; diff --git a/www/lang/Arduino_fr.js b/www/lang/Arduino_fr.js index a13d9928..a3f7d84a 100644 --- a/www/lang/Arduino_fr.js +++ b/www/lang/Arduino_fr.js @@ -213,13 +213,15 @@ Blockly.Msg.pixel2="mettre à jour les pixels"; Blockly.Msg.pixel3="avec la couleur"; Blockly.Msg.pixel4="nombre"; Blockly.Msg.pixel5="régler la luminosité des pixels à"; -Blockly.Msg.pixel6="régler la pixel"; +Blockly.Msg.pixel6="allumer la pixel"; Blockly.Msg.pixel7="éteindre les pixels"; +Blockly.Msg.pixel8="avec une couleur aléatoire"; Blockly.Msg.pixel1_tooltip="module neopixel RVB\nindiquer la broche à connecter et le nombre de pixels"; Blockly.Msg.pixel2_tooltip="affiche les modifications apportées"; Blockly.Msg.pixel3_tooltip="choisir la pixel à allumer ainsi que sa couleur\nAttention la numérotation commence à 0"; Blockly.Msg.pixel4_tooltip="éteint toutes les pixels"; Blockly.Msg.pixel5_tooltip="règle la luminosité des pixels (de 0 à 255)"; +Blockly.Msg.pixel6_tooltip="choisir la pixel à allumer ainsi qu'une couleur aléatoire\nAttention la numérotation commence à 0"; //sortie Blockly.Msg.ARDUINO_INOUT_DIGITAL_WRITE_INPUT1="mettre la broche NUMERIQUE"; Blockly.Msg.ARDUINO_INOUT_DIGITAL_WRITE_TOOLTIP="écrire un état logique (0 ou 1) sur la broche indiquée"; diff --git a/www/lang/code.js b/www/lang/code.js index 8c6dd223..a2dab6e3 100644 --- a/www/lang/code.js +++ b/www/lang/code.js @@ -42,6 +42,8 @@ Code.initLanguage = function() { languageMenu.append(option); } $('#span_theme').text(Blockly.Msg['span_theme']); + $('#span_renderer').text(Blockly.Msg['span_renderer']); + $('#span_library').text(Blockly.Msg['span_library']); $('#span_fontsize').text(Blockly.Msg['span_fontsize']); $('#span_card_connect').text(Blockly.Msg['span_card_connect']); $('#span_card_cpu').text(Blockly.Msg['span_card_cpu']); diff --git a/www/lang/msg_en.js b/www/lang/msg_en.js index d3c7acff..7be69b0a 100644 --- a/www/lang/msg_en.js +++ b/www/lang/msg_en.js @@ -68,7 +68,9 @@ Blockly.Msg.btn_add= " Add to workspace "; Blockly.Msg.btn_tint= " Colors "; Blockly.Msg.btn_games= " BLOCKLY-GAMES "; Blockly.Msg.span_fontsize= "Font size = "; -Blockly.Msg.span_theme= "Theme = "; +Blockly.Msg.span_theme= "Theme : "; +Blockly.Msg.span_renderer= "Renderer : "; +Blockly.Msg.span_library= "Library"; Blockly.Msg.span_card_connect= "Connector = "; Blockly.Msg.span_card_cpu= "CPU = "; Blockly.Msg.span_card_voltage= "Supply voltage = "; diff --git a/www/lang/msg_fr.js b/www/lang/msg_fr.js index 2b3b76d5..f1a9a424 100644 --- a/www/lang/msg_fr.js +++ b/www/lang/msg_fr.js @@ -69,6 +69,8 @@ Blockly.Msg.btn_tint= " couleurs "; Blockly.Msg.btn_games= " BLOCKLY-GAMES "; Blockly.Msg.span_fontsize= "Taille de police : "; Blockly.Msg.span_theme= "Thème : "; +Blockly.Msg.span_renderer= "Rendu : "; +Blockly.Msg.span_library= "Bibliothèque"; Blockly.Msg.span_card_connect= "Connecteur : "; Blockly.Msg.span_card_cpu= "CPU : "; Blockly.Msg.span_card_voltage= "Tension d'alimentation : "; diff --git a/www/modalVar.html b/www/modalVar.html index 81bc80bd..a03e2bea 100644 --- a/www/modalVar.html +++ b/www/modalVar.html @@ -16,7 +16,6 @@
-

diff --git a/www/splash.html b/www/splash.html deleted file mode 100644 index 0dd1fb61..00000000 --- a/www/splash.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - BLOCKLINO - - - - - - \ No newline at end of file diff --git a/www/toolbox/toolbox_arduino_all.xml b/www/toolbox/toolbox_arduino_all.xml index fc37c1f8..6fcc2d31 100644 --- a/www/toolbox/toolbox_arduino_all.xml +++ b/www/toolbox/toolbox_arduino_all.xml @@ -1,7 +1,7 @@ CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_TAB,CAT_VARIABLES,CAT_FUNCTIONS,CAT_ARDUINO,CAT_ARDUINO_IN,CAT_ARDUINO_TIME,CAT_actionneur,CAT_ultrason,CAT_com,CAT_STOCKAGE - + @@ -13,7 +13,7 @@ - + @@ -27,23 +27,23 @@ - + - + - - - + + + @@ -52,7 +52,7 @@ - + @@ -61,27 +61,28 @@ - + - - + + - - - + + + + - + @@ -89,7 +90,7 @@ - + @@ -98,7 +99,7 @@ - + @@ -107,11 +108,11 @@ - + - + @@ -124,8 +125,8 @@ - - + + @@ -135,7 +136,7 @@ - + @@ -150,8 +151,8 @@ - - + + @@ -159,7 +160,7 @@ - + @@ -167,13 +168,13 @@ - + - +