From 27680ee57f8db99b6765c76000f3520d0e0edcdc Mon Sep 17 00:00:00 2001 From: Camilo Date: Thu, 13 Jan 2022 23:24:55 +0100 Subject: [PATCH] GFX codes --- README.md | 1 + .../userlibs/libraries/AFMotor/AFMotor.cpp | 667 ++++++++++++++++++ .../userlibs/libraries/AFMotor/AFMotor.h | 181 +++++ .../userlibs/libraries/BME280/BME280.cpp | 392 ++++++++++ .../userlibs/libraries/BME280/BME280.h | 186 +++++ .../libraries/escornabot/escornabot.cpp | 433 ++++++++++++ .../libraries/escornabot/escornabot.h | 81 +++ .../escornabot/examples/buzzer/buzzer.ino | 20 + .../examples/line_follower/line_follower.ino | 45 ++ .../test_escornabot/test_escornabot.ino | 138 ++++ .../libraries/escornabot/examples/us/us.ino | 41 ++ .../libraries/escornabot/keywords.txt | 34 + .../libraries/escornabot/library.properties | 9 + www/blocs&generateurs/matrix.js | 80 ++- www/examples/examples.json | 138 ++-- www/examples/ninja.xml | 121 ++++ www/examples/ninjaapp.xml | 92 +++ www/lang/Arduino_en.js | 2 +- www/toolbox/toolbox_arduino_all-esp8266.xml | 102 +-- www/toolbox/toolbox_arduino_all.xml | 83 ++- 20 files changed, 2671 insertions(+), 175 deletions(-) create mode 100644 compilation/arduino/userlibs/libraries/AFMotor/AFMotor.cpp create mode 100644 compilation/arduino/userlibs/libraries/AFMotor/AFMotor.h create mode 100644 compilation/arduino/userlibs/libraries/BME280/BME280.cpp create mode 100644 compilation/arduino/userlibs/libraries/BME280/BME280.h create mode 100644 compilation/arduino/userlibs/libraries/escornabot/escornabot.cpp create mode 100644 compilation/arduino/userlibs/libraries/escornabot/escornabot.h create mode 100644 compilation/arduino/userlibs/libraries/escornabot/examples/buzzer/buzzer.ino create mode 100644 compilation/arduino/userlibs/libraries/escornabot/examples/line_follower/line_follower.ino create mode 100644 compilation/arduino/userlibs/libraries/escornabot/examples/test_escornabot/test_escornabot.ino create mode 100644 compilation/arduino/userlibs/libraries/escornabot/examples/us/us.ino create mode 100644 compilation/arduino/userlibs/libraries/escornabot/keywords.txt create mode 100644 compilation/arduino/userlibs/libraries/escornabot/library.properties create mode 100644 www/examples/ninja.xml create mode 100644 www/examples/ninjaapp.xml diff --git a/README.md b/README.md index c30bf748a..83f5d415f 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ Thanks to all these great people it has been possible to make this project: - [Ardublockly](https://github.com/carlosperate/ardublockly) - [Bodo Minea](https://github.com/BodoMinea) - [Takuji Kawata](https://github.com/takujikawata-pr) +- [Nicolas Nca78](https://github.com/Nca78/Matrix_GFX) - [Node.js](https://nodejs.org/) - [Bootstrap](http://getbootstrap.com) - [Font Awesome](http://fontawesome.io) diff --git a/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.cpp b/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.cpp new file mode 100644 index 000000000..c1f648273 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.cpp @@ -0,0 +1,667 @@ +// Adafruit Motor shield library +// copyright Adafruit Industries LLC, 2009 +// this code is public domain, enjoy! + + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #if defined(__AVR__) + #include + #endif + #include "WProgram.h" +#endif + +#include "AFMotor.h" + + + +static uint8_t latch_state; + +#if (MICROSTEPS == 8) +uint8_t microstepcurve[] = {0, 50, 98, 142, 180, 212, 236, 250, 255}; +#elif (MICROSTEPS == 16) +uint8_t microstepcurve[] = {0, 25, 50, 74, 98, 120, 141, 162, 180, 197, 212, 225, 236, 244, 250, 253, 255}; +#endif + +AFMotorController::AFMotorController(void) { + TimerInitalized = false; +} + +void AFMotorController::enable(void) { + // setup the latch + /* + LATCH_DDR |= _BV(LATCH); + ENABLE_DDR |= _BV(ENABLE); + CLK_DDR |= _BV(CLK); + SER_DDR |= _BV(SER); + */ + pinMode(MOTORLATCH, OUTPUT); + pinMode(MOTORENABLE, OUTPUT); + pinMode(MOTORDATA, OUTPUT); + pinMode(MOTORCLK, OUTPUT); + + latch_state = 0; + + latch_tx(); // "reset" + + //ENABLE_PORT &= ~_BV(ENABLE); // enable the chip outputs! + digitalWrite(MOTORENABLE, LOW); +} + + +void AFMotorController::latch_tx(void) { + uint8_t i; + + //LATCH_PORT &= ~_BV(LATCH); + digitalWrite(MOTORLATCH, LOW); + + //SER_PORT &= ~_BV(SER); + digitalWrite(MOTORDATA, LOW); + + for (i=0; i<8; i++) { + //CLK_PORT &= ~_BV(CLK); + digitalWrite(MOTORCLK, LOW); + + if (latch_state & _BV(7-i)) { + //SER_PORT |= _BV(SER); + digitalWrite(MOTORDATA, HIGH); + } else { + //SER_PORT &= ~_BV(SER); + digitalWrite(MOTORDATA, LOW); + } + //CLK_PORT |= _BV(CLK); + digitalWrite(MOTORCLK, HIGH); + } + //LATCH_PORT |= _BV(LATCH); + digitalWrite(MOTORLATCH, HIGH); +} + +static AFMotorController MC; + +/****************************************** + MOTORS +******************************************/ +inline void initPWM1(uint8_t freq) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer2A on PB3 (Arduino pin #11) + TCCR2A |= _BV(COM2A1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2a + TCCR2B = freq & 0x7; + OCR2A = 0; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 11 is now PB5 (OC1A) + TCCR1A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc1a + TCCR1B = (freq & 0x7) | _BV(WGM12); + OCR1A = 0; +#elif defined(__PIC32MX__) + #if defined(PIC32_USE_PIN9_FOR_M1_PWM) + // Make sure that pin 11 is an input, since we have tied together 9 and 11 + pinMode(9, OUTPUT); + pinMode(11, INPUT); + if (!MC.TimerInitalized) + { // Set up Timer2 for 80MHz counting fro 0 to 256 + T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0 + TMR2 = 0x0000; + PR2 = 0x0100; + MC.TimerInitalized = true; + } + // Setup OC4 (pin 9) in PWM mode, with Timer2 as timebase + OC4CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6 + OC4RS = 0x0000; + OC4R = 0x0000; + #elif defined(PIC32_USE_PIN10_FOR_M1_PWM) + // Make sure that pin 11 is an input, since we have tied together 9 and 11 + pinMode(10, OUTPUT); + pinMode(11, INPUT); + if (!MC.TimerInitalized) + { // Set up Timer2 for 80MHz counting fro 0 to 256 + T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0 + TMR2 = 0x0000; + PR2 = 0x0100; + MC.TimerInitalized = true; + } + // Setup OC5 (pin 10) in PWM mode, with Timer2 as timebase + OC5CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6 + OC5RS = 0x0000; + OC5R = 0x0000; + #else + // If we are not using PWM for pin 11, then just do digital + digitalWrite(11, LOW); + #endif +#else + #error "This chip is not supported!" +#endif + #if !defined(PIC32_USE_PIN9_FOR_M1_PWM) && !defined(PIC32_USE_PIN10_FOR_M1_PWM) + pinMode(11, OUTPUT); + #endif +} + +inline void setPWM1(uint8_t s) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer2A on PB3 (Arduino pin #11) + OCR2A = s; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 11 is now PB5 (OC1A) + OCR1A = s; +#elif defined(__PIC32MX__) + #if defined(PIC32_USE_PIN9_FOR_M1_PWM) + // Set the OC4 (pin 9) PMW duty cycle from 0 to 255 + OC4RS = s; + #elif defined(PIC32_USE_PIN10_FOR_M1_PWM) + // Set the OC5 (pin 10) PMW duty cycle from 0 to 255 + OC5RS = s; + #else + // If we are not doing PWM output for M1, then just use on/off + if (s > 127) + { + digitalWrite(11, HIGH); + } + else + { + digitalWrite(11, LOW); + } + #endif +#else + #error "This chip is not supported!" +#endif +} + +inline void initPWM2(uint8_t freq) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer2B (pin 3) + TCCR2A |= _BV(COM2B1) | _BV(WGM20) | _BV(WGM21); // fast PWM, turn on oc2b + TCCR2B = freq & 0x7; + OCR2B = 0; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 3 is now PE5 (OC3C) + TCCR3A |= _BV(COM1C1) | _BV(WGM10); // fast PWM, turn on oc3c + TCCR3B = (freq & 0x7) | _BV(WGM12); + OCR3C = 0; +#elif defined(__PIC32MX__) + if (!MC.TimerInitalized) + { // Set up Timer2 for 80MHz counting fro 0 to 256 + T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0 + TMR2 = 0x0000; + PR2 = 0x0100; + MC.TimerInitalized = true; + } + // Setup OC1 (pin3) in PWM mode, with Timer2 as timebase + OC1CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6 + OC1RS = 0x0000; + OC1R = 0x0000; +#else + #error "This chip is not supported!" +#endif + + pinMode(3, OUTPUT); +} + +inline void setPWM2(uint8_t s) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer2A on PB3 (Arduino pin #11) + OCR2B = s; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 11 is now PB5 (OC1A) + OCR3C = s; +#elif defined(__PIC32MX__) + // Set the OC1 (pin3) PMW duty cycle from 0 to 255 + OC1RS = s; +#else + #error "This chip is not supported!" +#endif +} + +inline void initPWM3(uint8_t freq) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer0A / PD6 (pin 6) + TCCR0A |= _BV(COM0A1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on OC0A + //TCCR0B = freq & 0x7; + OCR0A = 0; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 6 is now PH3 (OC4A) + TCCR4A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc4a + TCCR4B = (freq & 0x7) | _BV(WGM12); + //TCCR4B = 1 | _BV(WGM12); + OCR4A = 0; +#elif defined(__PIC32MX__) + if (!MC.TimerInitalized) + { // Set up Timer2 for 80MHz counting fro 0 to 256 + T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0 + TMR2 = 0x0000; + PR2 = 0x0100; + MC.TimerInitalized = true; + } + // Setup OC3 (pin 6) in PWM mode, with Timer2 as timebase + OC3CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6 + OC3RS = 0x0000; + OC3R = 0x0000; +#else + #error "This chip is not supported!" +#endif + pinMode(6, OUTPUT); +} + +inline void setPWM3(uint8_t s) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer0A on PB3 (Arduino pin #6) + OCR0A = s; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 6 is now PH3 (OC4A) + OCR4A = s; +#elif defined(__PIC32MX__) + // Set the OC3 (pin 6) PMW duty cycle from 0 to 255 + OC3RS = s; +#else + #error "This chip is not supported!" +#endif +} + + + +inline void initPWM4(uint8_t freq) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer0B / PD5 (pin 5) + TCCR0A |= _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); // fast PWM, turn on oc0a + //TCCR0B = freq & 0x7; + OCR0B = 0; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 5 is now PE3 (OC3A) + TCCR3A |= _BV(COM1A1) | _BV(WGM10); // fast PWM, turn on oc3a + TCCR3B = (freq & 0x7) | _BV(WGM12); + //TCCR4B = 1 | _BV(WGM12); + OCR3A = 0; +#elif defined(__PIC32MX__) + if (!MC.TimerInitalized) + { // Set up Timer2 for 80MHz counting fro 0 to 256 + T2CON = 0x8000 | ((freq & 0x07) << 4); // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=, T32=0, TCS=0; // ON=1, FRZ=0, SIDL=0, TGATE=0, TCKPS=0, T32=0, TCS=0 + TMR2 = 0x0000; + PR2 = 0x0100; + MC.TimerInitalized = true; + } + // Setup OC2 (pin 5) in PWM mode, with Timer2 as timebase + OC2CON = 0x8006; // OC32 = 0, OCTSEL=0, OCM=6 + OC2RS = 0x0000; + OC2R = 0x0000; +#else + #error "This chip is not supported!" +#endif + pinMode(5, OUTPUT); +} + +inline void setPWM4(uint8_t s) { +#if defined(__AVR_ATmega8__) || \ + defined(__AVR_ATmega48__) || \ + defined(__AVR_ATmega88__) || \ + defined(__AVR_ATmega168__) || \ + defined(__AVR_ATmega328P__) + // use PWM from timer0A on PB3 (Arduino pin #6) + OCR0B = s; +#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) + // on arduino mega, pin 6 is now PH3 (OC4A) + OCR3A = s; +#elif defined(__PIC32MX__) + // Set the OC2 (pin 5) PMW duty cycle from 0 to 255 + OC2RS = s; +#else + #error "This chip is not supported!" +#endif +} + +AF_DCMotor::AF_DCMotor(uint8_t num, uint8_t freq) { + motornum = num; + pwmfreq = freq; + + MC.enable(); + + switch (num) { + case 1: + latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B); // set both motor pins to 0 + MC.latch_tx(); + initPWM1(freq); + break; + case 2: + latch_state &= ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // set both motor pins to 0 + MC.latch_tx(); + initPWM2(freq); + break; + case 3: + latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B); // set both motor pins to 0 + MC.latch_tx(); + initPWM3(freq); + break; + case 4: + latch_state &= ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // set both motor pins to 0 + MC.latch_tx(); + initPWM4(freq); + break; + } +} + +void AF_DCMotor::run(uint8_t cmd) { + uint8_t a, b; + switch (motornum) { + case 1: + a = MOTOR1_A; b = MOTOR1_B; break; + case 2: + a = MOTOR2_A; b = MOTOR2_B; break; + case 3: + a = MOTOR3_A; b = MOTOR3_B; break; + case 4: + a = MOTOR4_A; b = MOTOR4_B; break; + default: + return; + } + + switch (cmd) { + case FORWARD: + latch_state |= _BV(a); + latch_state &= ~_BV(b); + MC.latch_tx(); + break; + case BACKWARD: + latch_state &= ~_BV(a); + latch_state |= _BV(b); + MC.latch_tx(); + break; + case RELEASE: + latch_state &= ~_BV(a); // A and B both low + latch_state &= ~_BV(b); + MC.latch_tx(); + break; + } +} + +void AF_DCMotor::setSpeed(uint8_t speed) { + switch (motornum) { + case 1: + setPWM1(speed); break; + case 2: + setPWM2(speed); break; + case 3: + setPWM3(speed); break; + case 4: + setPWM4(speed); break; + } +} + +/****************************************** + STEPPERS +******************************************/ + +AF_Stepper::AF_Stepper(uint16_t steps, uint8_t num) { + MC.enable(); + + revsteps = steps; + steppernum = num; + currentstep = 0; + + if (steppernum == 1) { + latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) & + ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0 + MC.latch_tx(); + + // enable both H bridges + pinMode(11, OUTPUT); + pinMode(3, OUTPUT); + digitalWrite(11, HIGH); + digitalWrite(3, HIGH); + + // use PWM for microstepping support + initPWM1(STEPPER1_PWM_RATE); + initPWM2(STEPPER1_PWM_RATE); + setPWM1(255); + setPWM2(255); + + } else if (steppernum == 2) { + latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) & + ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0 + MC.latch_tx(); + + // enable both H bridges + pinMode(5, OUTPUT); + pinMode(6, OUTPUT); + digitalWrite(5, HIGH); + digitalWrite(6, HIGH); + + // use PWM for microstepping support + // use PWM for microstepping support + initPWM3(STEPPER2_PWM_RATE); + initPWM4(STEPPER2_PWM_RATE); + setPWM3(255); + setPWM4(255); + } +} + +void AF_Stepper::setSpeed(uint16_t rpm) { + usperstep = 60000000 / ((uint32_t)revsteps * (uint32_t)rpm); + steppingcounter = 0; +} + +void AF_Stepper::release(void) { + if (steppernum == 1) { + latch_state &= ~_BV(MOTOR1_A) & ~_BV(MOTOR1_B) & + ~_BV(MOTOR2_A) & ~_BV(MOTOR2_B); // all motor pins to 0 + MC.latch_tx(); + } else if (steppernum == 2) { + latch_state &= ~_BV(MOTOR3_A) & ~_BV(MOTOR3_B) & + ~_BV(MOTOR4_A) & ~_BV(MOTOR4_B); // all motor pins to 0 + MC.latch_tx(); + } +} + +void AF_Stepper::step(uint16_t steps, uint8_t dir, uint8_t style) { + uint32_t uspers = usperstep; + uint8_t ret = 0; + + if (style == INTERLEAVE) { + uspers /= 2; + } + else if (style == MICROSTEP) { + uspers /= MICROSTEPS; + steps *= MICROSTEPS; +#ifdef MOTORDEBUG + Serial.print("steps = "); Serial.println(steps, DEC); +#endif + } + + while (steps--) { + ret = onestep(dir, style); + delay(uspers/1000); // in ms + steppingcounter += (uspers % 1000); + if (steppingcounter >= 1000) { + delay(1); + steppingcounter -= 1000; + } + } + if (style == MICROSTEP) { + while ((ret != 0) && (ret != MICROSTEPS)) { + ret = onestep(dir, style); + delay(uspers/1000); // in ms + steppingcounter += (uspers % 1000); + if (steppingcounter >= 1000) { + delay(1); + steppingcounter -= 1000; + } + } + } +} + +uint8_t AF_Stepper::onestep(uint8_t dir, uint8_t style) { + uint8_t a, b, c, d; + uint8_t ocrb, ocra; + + ocra = ocrb = 255; + + if (steppernum == 1) { + a = _BV(MOTOR1_A); + b = _BV(MOTOR2_A); + c = _BV(MOTOR1_B); + d = _BV(MOTOR2_B); + } else if (steppernum == 2) { + a = _BV(MOTOR3_A); + b = _BV(MOTOR4_A); + c = _BV(MOTOR3_B); + d = _BV(MOTOR4_B); + } else { + return 0; + } + + // next determine what sort of stepping procedure we're up to + if (style == SINGLE) { + if ((currentstep/(MICROSTEPS/2)) % 2) { // we're at an odd step, weird + if (dir == FORWARD) { + currentstep += MICROSTEPS/2; + } + else { + currentstep -= MICROSTEPS/2; + } + } else { // go to the next even step + if (dir == FORWARD) { + currentstep += MICROSTEPS; + } + else { + currentstep -= MICROSTEPS; + } + } + } else if (style == DOUBLE) { + if (! (currentstep/(MICROSTEPS/2) % 2)) { // we're at an even step, weird + if (dir == FORWARD) { + currentstep += MICROSTEPS/2; + } else { + currentstep -= MICROSTEPS/2; + } + } else { // go to the next odd step + if (dir == FORWARD) { + currentstep += MICROSTEPS; + } else { + currentstep -= MICROSTEPS; + } + } + } else if (style == INTERLEAVE) { + if (dir == FORWARD) { + currentstep += MICROSTEPS/2; + } else { + currentstep -= MICROSTEPS/2; + } + } + + if (style == MICROSTEP) { + if (dir == FORWARD) { + currentstep++; + } else { + // BACKWARDS + currentstep--; + } + + currentstep += MICROSTEPS*4; + currentstep %= MICROSTEPS*4; + + ocra = ocrb = 0; + if ( (currentstep >= 0) && (currentstep < MICROSTEPS)) { + ocra = microstepcurve[MICROSTEPS - currentstep]; + ocrb = microstepcurve[currentstep]; + } else if ( (currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) { + ocra = microstepcurve[currentstep - MICROSTEPS]; + ocrb = microstepcurve[MICROSTEPS*2 - currentstep]; + } else if ( (currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) { + ocra = microstepcurve[MICROSTEPS*3 - currentstep]; + ocrb = microstepcurve[currentstep - MICROSTEPS*2]; + } else if ( (currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) { + ocra = microstepcurve[currentstep - MICROSTEPS*3]; + ocrb = microstepcurve[MICROSTEPS*4 - currentstep]; + } + } + + currentstep += MICROSTEPS*4; + currentstep %= MICROSTEPS*4; + +#ifdef MOTORDEBUG + Serial.print("current step: "); Serial.println(currentstep, DEC); + Serial.print(" pwmA = "); Serial.print(ocra, DEC); + Serial.print(" pwmB = "); Serial.println(ocrb, DEC); +#endif + + if (steppernum == 1) { + setPWM1(ocra); + setPWM2(ocrb); + } else if (steppernum == 2) { + setPWM3(ocra); + setPWM4(ocrb); + } + + + // release all + latch_state &= ~a & ~b & ~c & ~d; // all motor pins to 0 + + //Serial.println(step, DEC); + if (style == MICROSTEP) { + if ((currentstep >= 0) && (currentstep < MICROSTEPS)) + latch_state |= a | b; + if ((currentstep >= MICROSTEPS) && (currentstep < MICROSTEPS*2)) + latch_state |= b | c; + if ((currentstep >= MICROSTEPS*2) && (currentstep < MICROSTEPS*3)) + latch_state |= c | d; + if ((currentstep >= MICROSTEPS*3) && (currentstep < MICROSTEPS*4)) + latch_state |= d | a; + } else { + switch (currentstep/(MICROSTEPS/2)) { + case 0: + latch_state |= a; // energize coil 1 only + break; + case 1: + latch_state |= a | b; // energize coil 1+2 + break; + case 2: + latch_state |= b; // energize coil 2 only + break; + case 3: + latch_state |= b | c; // energize coil 2+3 + break; + case 4: + latch_state |= c; // energize coil 3 only + break; + case 5: + latch_state |= c | d; // energize coil 3+4 + break; + case 6: + latch_state |= d; // energize coil 4 only + break; + case 7: + latch_state |= d | a; // energize coil 1+4 + break; + } + } + + + MC.latch_tx(); + return currentstep; +} + diff --git a/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.h b/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.h new file mode 100644 index 000000000..0362211fa --- /dev/null +++ b/compilation/arduino/userlibs/libraries/AFMotor/AFMotor.h @@ -0,0 +1,181 @@ +// Adafruit Motor shield library +// copyright Adafruit Industries LLC, 2009 +// this code is public domain, enjoy! + +/* + * Usage Notes: + * For PIC32, all features work properly with the following two exceptions: + * + * 1) Because the PIC32 only has 5 PWM outputs, and the AFMotor shield needs 6 + * to completely operate (for for motor outputs and two for RC servos), the + * M1 motor output will not have PWM ability when used with a PIC32 board. + * However, there is a very simple workaround. If you need to drive a stepper + * or DC motor with PWM on motor output M1, you can use the PWM output on pin + * 9 or pin 10 (normally use for RC servo outputs on Arduino, not needed for + * RC servo outputs on PIC32) to drive the PWM input for M1 by simply putting + * a jumber from pin 9 to pin 11 or pin 10 to pin 11. Then uncomment one of the + * two #defines below to activate the PWM on either pin 9 or pin 10. You will + * then have a fully functional microstepping for 2 stepper motors, or four + * DC motor outputs with PWM. + * + * 2) There is a conflict between RC Servo outputs on pins 9 and pins 10 and + * the operation of DC motors and stepper motors as of 9/2012. This issue + * will get fixed in future MPIDE releases, but at the present time it means + * that the Motor Party example will NOT work properly. Any time you attach + * an RC servo to pins 9 or pins 10, ALL PWM outputs on the whole board will + * stop working. Thus no steppers or DC motors. + * + */ +// 09/15/2012 Modified for use with chipKIT boards + + +#ifndef _AFMotor_h_ +#define _AFMotor_h_ + +#include +#if defined(__AVR__) + #include + + //#define MOTORDEBUG 1 + + #define MICROSTEPS 16 // 8 or 16 + + #define MOTOR12_64KHZ _BV(CS20) // no prescale + #define MOTOR12_8KHZ _BV(CS21) // divide by 8 + #define MOTOR12_2KHZ _BV(CS21) | _BV(CS20) // divide by 32 + #define MOTOR12_1KHZ _BV(CS22) // divide by 64 + + #define MOTOR34_64KHZ _BV(CS00) // no prescale + #define MOTOR34_8KHZ _BV(CS01) // divide by 8 + #define MOTOR34_1KHZ _BV(CS01) | _BV(CS00) // divide by 64 + + #define DC_MOTOR_PWM_RATE MOTOR34_8KHZ // PWM rate for DC motors + #define STEPPER1_PWM_RATE MOTOR12_64KHZ // PWM rate for stepper 1 + #define STEPPER2_PWM_RATE MOTOR34_64KHZ // PWM rate for stepper 2 + +#elif defined(__PIC32MX__) + //#define MOTORDEBUG 1 + + // Uncomment the one of following lines if you have put a jumper from + // either pin 9 to pin 11 or pin 10 to pin 11 on your Motor Shield. + // Either will enable PWM for M1 + //#define PIC32_USE_PIN9_FOR_M1_PWM + //#define PIC32_USE_PIN10_FOR_M1_PWM + + #define MICROSTEPS 16 // 8 or 16 + + // For PIC32 Timers, define prescale settings by PWM frequency + #define MOTOR12_312KHZ 0 // 1:1, actual frequency 312KHz + #define MOTOR12_156KHZ 1 // 1:2, actual frequency 156KHz + #define MOTOR12_64KHZ 2 // 1:4, actual frequency 78KHz + #define MOTOR12_39KHZ 3 // 1:8, acutal frequency 39KHz + #define MOTOR12_19KHZ 4 // 1:16, actual frequency 19KHz + #define MOTOR12_8KHZ 5 // 1:32, actual frequency 9.7KHz + #define MOTOR12_4_8KHZ 6 // 1:64, actual frequency 4.8KHz + #define MOTOR12_2KHZ 7 // 1:256, actual frequency 1.2KHz + #define MOTOR12_1KHZ 7 // 1:256, actual frequency 1.2KHz + + #define MOTOR34_312KHZ 0 // 1:1, actual frequency 312KHz + #define MOTOR34_156KHZ 1 // 1:2, actual frequency 156KHz + #define MOTOR34_64KHZ 2 // 1:4, actual frequency 78KHz + #define MOTOR34_39KHZ 3 // 1:8, acutal frequency 39KHz + #define MOTOR34_19KHZ 4 // 1:16, actual frequency 19KHz + #define MOTOR34_8KHZ 5 // 1:32, actual frequency 9.7KHz + #define MOTOR34_4_8KHZ 6 // 1:64, actual frequency 4.8KHz + #define MOTOR34_2KHZ 7 // 1:256, actual frequency 1.2KHz + #define MOTOR34_1KHZ 7 // 1:256, actual frequency 1.2KHz + + // PWM rate for DC motors. + #define DC_MOTOR_PWM_RATE MOTOR34_39KHZ + // Note: for PIC32, both of these must be set to the same value + // since there's only one timebase for all 4 PWM outputs + #define STEPPER1_PWM_RATE MOTOR12_39KHZ + #define STEPPER2_PWM_RATE MOTOR34_39KHZ + +#endif + +// Bit positions in the 74HCT595 shift register output +#define MOTOR1_A 2 +#define MOTOR1_B 3 +#define MOTOR2_A 1 +#define MOTOR2_B 4 +#define MOTOR4_A 0 +#define MOTOR4_B 6 +#define MOTOR3_A 5 +#define MOTOR3_B 7 + +// Constants that the user passes in to the motor calls +#define FORWARD 1 +#define BACKWARD 2 +#define BRAKE 3 +#define RELEASE 4 + +// Constants that the user passes in to the stepper calls +#define SINGLE 1 +#define DOUBLE 2 +#define INTERLEAVE 3 +#define MICROSTEP 4 + +/* +#define LATCH 4 +#define LATCH_DDR DDRB +#define LATCH_PORT PORTB + +#define CLK_PORT PORTD +#define CLK_DDR DDRD +#define CLK 4 + +#define ENABLE_PORT PORTD +#define ENABLE_DDR DDRD +#define ENABLE 7 + +#define SER 0 +#define SER_DDR DDRB +#define SER_PORT PORTB +*/ + +// Arduino pin names for interface to 74HCT595 latch +#define MOTORLATCH 12 +#define MOTORCLK 4 +#define MOTORENABLE 7 +#define MOTORDATA 8 + +class AFMotorController +{ + public: + AFMotorController(void); + void enable(void); + friend class AF_DCMotor; + void latch_tx(void); + uint8_t TimerInitalized; +}; + +class AF_DCMotor +{ + public: + AF_DCMotor(uint8_t motornum, uint8_t freq = DC_MOTOR_PWM_RATE); + void run(uint8_t); + void setSpeed(uint8_t); + + private: + uint8_t motornum, pwmfreq; +}; + +class AF_Stepper { + public: + AF_Stepper(uint16_t, uint8_t); + void step(uint16_t steps, uint8_t dir, uint8_t style = SINGLE); + void setSpeed(uint16_t); + uint8_t onestep(uint8_t dir, uint8_t style); + void release(void); + uint16_t revsteps; // # steps per revolution + uint8_t steppernum; + uint32_t usperstep, steppingcounter; + private: + uint8_t currentstep; + +}; + +uint8_t getlatchstate(void); + +#endif diff --git a/compilation/arduino/userlibs/libraries/BME280/BME280.cpp b/compilation/arduino/userlibs/libraries/BME280/BME280.cpp new file mode 100644 index 000000000..8e090c9e9 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/BME280/BME280.cpp @@ -0,0 +1,392 @@ +/****************************************************************************** +SparkFunBME280.cpp +BME280 Arduino and Teensy Driver +Marshall Taylor @ SparkFun Electronics +May 20, 2015 +https://github.com/sparkfun/BME280_Breakout + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. +Distributed as-is; no warranty is given. +******************************************************************************/ +//See SparkFunBME280.h for additional topology notes. + +#include "SparkFunBME280.h" +#include "stdint.h" +#include + +#include "Wire.h" +#include "SPI.h" + +//****************************************************************************// +// +// Settings and configuration +// +//****************************************************************************// + +//Constructor -- Specifies default configuration +BME280::BME280( void ) +{ + //Construct with these default settings if nothing is specified + + //Select interface mode + settings.commInterface = I2C_MODE; //Can be I2C_MODE, SPI_MODE + //Select address for I2C. Does nothing for SPI + settings.I2CAddress = 0x77; //Ignored for SPI_MODE + //Select CS pin for SPI. Does nothing for I2C + settings.chipSelectPin = 10; + settings.runMode = 0; + settings.tempOverSample = 0; + settings.pressOverSample = 0; + settings.humidOverSample = 0; + +} + + +//****************************************************************************// +// +// Configuration section +// +// This uses the stored SensorSettings to start the IMU +// Use statements such as "mySensor.settings.commInterface = SPI_MODE;" to +// configure before calling .begin(); +// +//****************************************************************************// +uint8_t BME280::begin() +{ + //Check the settings structure values to determine how to setup the device + uint8_t dataToWrite = 0; //Temporary variable + + switch (settings.commInterface) + { + + case I2C_MODE: + Wire.begin(); + break; + + case SPI_MODE: + // start the SPI library: + SPI.begin(); + // Maximum SPI frequency is 10MHz, could divide by 2 here: + SPI.setClockDivider(SPI_CLOCK_DIV32); + // Data is read and written MSb first. + SPI.setBitOrder(MSBFIRST); + // Data is captured on rising edge of clock (CPHA = 0) + // Base value of the clock is HIGH (CPOL = 1) + // This was SPI_MODE3 for RedBoard, but I had to change to + // MODE0 for Teensy 3.1 operation + SPI.setDataMode(SPI_MODE3); + // initalize the data ready and chip select pins: + pinMode(settings.chipSelectPin, OUTPUT); + digitalWrite(settings.chipSelectPin, HIGH); + break; + + default: + break; + } + + //Reading all compensation data, range 0x88:A1, 0xE1:E7 + + calibration.dig_T1 = ((uint16_t)((readRegister(BME280_DIG_T1_MSB_REG) << 8) + readRegister(BME280_DIG_T1_LSB_REG))); + calibration.dig_T2 = ((int16_t)((readRegister(BME280_DIG_T2_MSB_REG) << 8) + readRegister(BME280_DIG_T2_LSB_REG))); + calibration.dig_T3 = ((int16_t)((readRegister(BME280_DIG_T3_MSB_REG) << 8) + readRegister(BME280_DIG_T3_LSB_REG))); + + calibration.dig_P1 = ((uint16_t)((readRegister(BME280_DIG_P1_MSB_REG) << 8) + readRegister(BME280_DIG_P1_LSB_REG))); + calibration.dig_P2 = ((int16_t)((readRegister(BME280_DIG_P2_MSB_REG) << 8) + readRegister(BME280_DIG_P2_LSB_REG))); + calibration.dig_P3 = ((int16_t)((readRegister(BME280_DIG_P3_MSB_REG) << 8) + readRegister(BME280_DIG_P3_LSB_REG))); + calibration.dig_P4 = ((int16_t)((readRegister(BME280_DIG_P4_MSB_REG) << 8) + readRegister(BME280_DIG_P4_LSB_REG))); + calibration.dig_P5 = ((int16_t)((readRegister(BME280_DIG_P5_MSB_REG) << 8) + readRegister(BME280_DIG_P5_LSB_REG))); + calibration.dig_P6 = ((int16_t)((readRegister(BME280_DIG_P6_MSB_REG) << 8) + readRegister(BME280_DIG_P6_LSB_REG))); + calibration.dig_P7 = ((int16_t)((readRegister(BME280_DIG_P7_MSB_REG) << 8) + readRegister(BME280_DIG_P7_LSB_REG))); + calibration.dig_P8 = ((int16_t)((readRegister(BME280_DIG_P8_MSB_REG) << 8) + readRegister(BME280_DIG_P8_LSB_REG))); + calibration.dig_P9 = ((int16_t)((readRegister(BME280_DIG_P9_MSB_REG) << 8) + readRegister(BME280_DIG_P9_LSB_REG))); + + calibration.dig_H1 = ((uint8_t)(readRegister(BME280_DIG_H1_REG))); + calibration.dig_H2 = ((int16_t)((readRegister(BME280_DIG_H2_MSB_REG) << 8) + readRegister(BME280_DIG_H2_LSB_REG))); + calibration.dig_H3 = ((uint8_t)(readRegister(BME280_DIG_H3_REG))); + calibration.dig_H4 = ((int16_t)((readRegister(BME280_DIG_H4_MSB_REG) << 4) + (readRegister(BME280_DIG_H4_LSB_REG) & 0x0F))); + calibration.dig_H5 = ((int16_t)((readRegister(BME280_DIG_H5_MSB_REG) << 4) + ((readRegister(BME280_DIG_H4_LSB_REG) >> 4) & 0x0F))); + calibration.dig_H6 = ((uint8_t)readRegister(BME280_DIG_H6_REG)); + + //Set the oversampling control words. + //config will only be writeable in sleep mode, so first insure that. + writeRegister(BME280_CTRL_MEAS_REG, 0x00); + + //Set the config word + dataToWrite = (settings.tStandby << 0x5) & 0xE0; + dataToWrite |= (settings.filter << 0x02) & 0x1C; + writeRegister(BME280_CONFIG_REG, dataToWrite); + + //Set ctrl_hum first, then ctrl_meas to activate ctrl_hum + dataToWrite = settings.humidOverSample & 0x07; //all other bits can be ignored + writeRegister(BME280_CTRL_HUMIDITY_REG, dataToWrite); + + //set ctrl_meas + //First, set temp oversampling + dataToWrite = (settings.tempOverSample << 0x5) & 0xE0; + //Next, pressure oversampling + dataToWrite |= (settings.pressOverSample << 0x02) & 0x1C; + //Last, set mode + dataToWrite |= (settings.runMode) & 0x03; + //Load the byte + writeRegister(BME280_CTRL_MEAS_REG, dataToWrite); + + return readRegister(0xD0); +} + +//Strictly resets. Run .begin() afterwards +void BME280::reset( void ) +{ + writeRegister(BME280_RST_REG, 0xB6); + +} + +//****************************************************************************// +// +// Pressure Section +// +//****************************************************************************// +float BME280::readFloatPressure( void ) +{ + + // Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits). + // Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa + int32_t adc_P = ((uint32_t)readRegister(BME280_PRESSURE_MSB_REG) << 12) | ((uint32_t)readRegister(BME280_PRESSURE_LSB_REG) << 4) | ((readRegister(BME280_PRESSURE_XLSB_REG) >> 4) & 0x0F); + + int64_t var1, var2, p_acc; + var1 = ((int64_t)t_fine) - 128000; + var2 = var1 * var1 * (int64_t)calibration.dig_P6; + var2 = var2 + ((var1 * (int64_t)calibration.dig_P5)<<17); + var2 = var2 + (((int64_t)calibration.dig_P4)<<35); + var1 = ((var1 * var1 * (int64_t)calibration.dig_P3)>>8) + ((var1 * (int64_t)calibration.dig_P2)<<12); + var1 = (((((int64_t)1)<<47)+var1))*((int64_t)calibration.dig_P1)>>33; + if (var1 == 0) + { + return 0; // avoid exception caused by division by zero + } + p_acc = 1048576 - adc_P; + p_acc = (((p_acc<<31) - var2)*3125)/var1; + var1 = (((int64_t)calibration.dig_P9) * (p_acc>>13) * (p_acc>>13)) >> 25; + var2 = (((int64_t)calibration.dig_P8) * p_acc) >> 19; + p_acc = ((p_acc + var1 + var2) >> 8) + (((int64_t)calibration.dig_P7)<<4); + + p_acc = p_acc >> 8; // /256 + return (float)p_acc; + +} + +float BME280::readFloatAltitudeMeters( void ) +{ + float heightOutput = 0; + + heightOutput = ((float)-45846.2)*(pow(((float)readFloatPressure()/(float)101325), 0.190263) - (float)1); + return heightOutput; + +} + +float BME280::readFloatAltitudeFeet( void ) +{ + float heightOutput = 0; + + heightOutput = readFloatAltitudeMeters() * 3.28084; + return heightOutput; + +} + +//****************************************************************************// +// +// Humidity Section +// +//****************************************************************************// +float BME280::readFloatHumidity( void ) +{ + + // Returns humidity in %RH as unsigned 32 bit integer in Q22. 10 format (22 integer and 10 fractional bits). + // Output value of “47445” represents 47445/1024 = 46. 333 %RH + int32_t adc_H = ((uint32_t)readRegister(BME280_HUMIDITY_MSB_REG) << 8) | ((uint32_t)readRegister(BME280_HUMIDITY_LSB_REG)); + + int32_t var1; + var1 = (t_fine - ((int32_t)76800)); + var1 = (((((adc_H << 14) - (((int32_t)calibration.dig_H4) << 20) - (((int32_t)calibration.dig_H5) * var1)) + + ((int32_t)16384)) >> 15) * (((((((var1 * ((int32_t)calibration.dig_H6)) >> 10) * (((var1 * ((int32_t)calibration.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * + ((int32_t)calibration.dig_H2) + 8192) >> 14)); + var1 = (var1 - (((((var1 >> 15) * (var1 >> 15)) >> 7) * ((int32_t)calibration.dig_H1)) >> 4)); + var1 = (var1 < 0 ? 0 : var1); + var1 = (var1 > 419430400 ? 419430400 : var1); + + return (float)((var1>>12) >> 10); + +} + + + +//****************************************************************************// +// +// Temperature Section +// +//****************************************************************************// + +float BME280::readTempC( void ) +{ + // Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC. + // t_fine carries fine temperature as global value + + //get the reading (adc_T); + int32_t adc_T = ((uint32_t)readRegister(BME280_TEMPERATURE_MSB_REG) << 12) | ((uint32_t)readRegister(BME280_TEMPERATURE_LSB_REG) << 4) | ((readRegister(BME280_TEMPERATURE_XLSB_REG) >> 4) & 0x0F); + + //By datasheet, calibrate + int64_t var1, var2; + + var1 = ((((adc_T>>3) - ((int32_t)calibration.dig_T1<<1))) * ((int32_t)calibration.dig_T2)) >> 11; + var2 = (((((adc_T>>4) - ((int32_t)calibration.dig_T1)) * ((adc_T>>4) - ((int32_t)calibration.dig_T1))) >> 12) * + ((int32_t)calibration.dig_T3)) >> 14; + t_fine = var1 + var2; + float output = (t_fine * 5 + 128) >> 8; + + output = output / 100; + + return output; +} + +float BME280::readTempF( void ) +{ + float output = readTempC(); + output = (output * 9) / 5 + 32; + + return output; +} + +//****************************************************************************// +// +// Utility +// +//****************************************************************************// +void BME280::readRegisterRegion(uint8_t *outputPointer , uint8_t offset, uint8_t length) +{ + //define pointer that will point to the external space + uint8_t i = 0; + char c = 0; + + switch (settings.commInterface) + { + + case I2C_MODE: + Wire.beginTransmission(settings.I2CAddress); + Wire.write(offset); + Wire.endTransmission(); + + // request bytes from slave device + Wire.requestFrom(settings.I2CAddress, length); + while ( (Wire.available()) && (i < length)) // slave may send less than requested + { + c = Wire.read(); // receive a byte as character + *outputPointer = c; + outputPointer++; + i++; + } + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(settings.chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset | 0x80); //Ored with "read request" bit + while ( i < length ) // slave may send less than requested + { + c = SPI.transfer(0x00); // receive a byte as character + *outputPointer = c; + outputPointer++; + i++; + } + // take the chip select high to de-select: + digitalWrite(settings.chipSelectPin, HIGH); + break; + + default: + break; + } + +} + +uint8_t BME280::readRegister(uint8_t offset) +{ + //Return value + uint8_t result; + uint8_t numBytes = 1; + switch (settings.commInterface) { + + case I2C_MODE: + Wire.beginTransmission(settings.I2CAddress); + Wire.write(offset); + Wire.endTransmission(); + + Wire.requestFrom(settings.I2CAddress, numBytes); + while ( Wire.available() ) // slave may send less than requested + { + result = Wire.read(); // receive a byte as a proper uint8_t + } + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(settings.chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset | 0x80); //Ored with "read request" bit + // send a value of 0 to read the first byte returned: + result = SPI.transfer(0x00); + // take the chip select high to de-select: + digitalWrite(settings.chipSelectPin, HIGH); + break; + + default: + break; + } + return result; +} + +int16_t BME280::readRegisterInt16( uint8_t offset ) +{ + uint8_t myBuffer[2]; + readRegisterRegion(myBuffer, offset, 2); //Does memory transfer + int16_t output = (int16_t)myBuffer[0] | int16_t(myBuffer[1] << 8); + + return output; +} + +void BME280::writeRegister(uint8_t offset, uint8_t dataToWrite) +{ + switch (settings.commInterface) + { + case I2C_MODE: + //Write the byte + Wire.beginTransmission(settings.I2CAddress); + Wire.write(offset); + Wire.write(dataToWrite); + Wire.endTransmission(); + break; + + case SPI_MODE: + // take the chip select low to select the device: + digitalWrite(settings.chipSelectPin, LOW); + // send the device the register you want to read: + SPI.transfer(offset & 0x7F); + // send a value of 0 to read the first byte returned: + SPI.transfer(dataToWrite); + // decrement the number of bytes left to read: + // take the chip select high to de-select: + digitalWrite(settings.chipSelectPin, HIGH); + break; + + default: + break; + } +} diff --git a/compilation/arduino/userlibs/libraries/BME280/BME280.h b/compilation/arduino/userlibs/libraries/BME280/BME280.h new file mode 100644 index 000000000..f1a53d166 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/BME280/BME280.h @@ -0,0 +1,186 @@ +/****************************************************************************** +SparkFunBME280.h +BME280 Arduino and Teensy Driver +Marshall Taylor @ SparkFun Electronics +May 20, 2015 +https://github.com/sparkfun/BME280_Breakout + +Resources: +Uses Wire.h for i2c operation +Uses SPI.h for SPI operation + +Development environment specifics: +Arduino IDE 1.6.4 +Teensy loader 1.23 + +This code is released under the [MIT License](http://opensource.org/licenses/MIT). +Please review the LICENSE.md file included with this example. If you have any questions +or concerns with licensing, please contact techsupport@sparkfun.com. +Distributed as-is; no warranty is given. +******************************************************************************/ + +// Test derived class for base class SparkFunIMU +#ifndef __BME280_H__ +#define __BME280_H__ + +#include "stdint.h" + +#define I2C_MODE 0 +#define SPI_MODE 1 + +//Register names: +#define BME280_DIG_T1_LSB_REG 0x88 +#define BME280_DIG_T1_MSB_REG 0x89 +#define BME280_DIG_T2_LSB_REG 0x8A +#define BME280_DIG_T2_MSB_REG 0x8B +#define BME280_DIG_T3_LSB_REG 0x8C +#define BME280_DIG_T3_MSB_REG 0x8D +#define BME280_DIG_P1_LSB_REG 0x8E +#define BME280_DIG_P1_MSB_REG 0x8F +#define BME280_DIG_P2_LSB_REG 0x90 +#define BME280_DIG_P2_MSB_REG 0x91 +#define BME280_DIG_P3_LSB_REG 0x92 +#define BME280_DIG_P3_MSB_REG 0x93 +#define BME280_DIG_P4_LSB_REG 0x94 +#define BME280_DIG_P4_MSB_REG 0x95 +#define BME280_DIG_P5_LSB_REG 0x96 +#define BME280_DIG_P5_MSB_REG 0x97 +#define BME280_DIG_P6_LSB_REG 0x98 +#define BME280_DIG_P6_MSB_REG 0x99 +#define BME280_DIG_P7_LSB_REG 0x9A +#define BME280_DIG_P7_MSB_REG 0x9B +#define BME280_DIG_P8_LSB_REG 0x9C +#define BME280_DIG_P8_MSB_REG 0x9D +#define BME280_DIG_P9_LSB_REG 0x9E +#define BME280_DIG_P9_MSB_REG 0x9F +#define BME280_DIG_H1_REG 0xA1 +#define BME280_CHIP_ID_REG 0xD0 //Chip ID +#define BME280_RST_REG 0xE0 //Softreset Reg +#define BME280_DIG_H2_LSB_REG 0xE1 +#define BME280_DIG_H2_MSB_REG 0xE2 +#define BME280_DIG_H3_REG 0xE3 +#define BME280_DIG_H4_MSB_REG 0xE4 +#define BME280_DIG_H4_LSB_REG 0xE5 +#define BME280_DIG_H5_MSB_REG 0xE6 +#define BME280_DIG_H6_REG 0xE7 +#define BME280_CTRL_HUMIDITY_REG 0xF2 //Ctrl Humidity Reg +#define BME280_STAT_REG 0xF3 //Status Reg +#define BME280_CTRL_MEAS_REG 0xF4 //Ctrl Measure Reg +#define BME280_CONFIG_REG 0xF5 //Configuration Reg +#define BME280_PRESSURE_MSB_REG 0xF7 //Pressure MSB +#define BME280_PRESSURE_LSB_REG 0xF8 //Pressure LSB +#define BME280_PRESSURE_XLSB_REG 0xF9 //Pressure XLSB +#define BME280_TEMPERATURE_MSB_REG 0xFA //Temperature MSB +#define BME280_TEMPERATURE_LSB_REG 0xFB //Temperature LSB +#define BME280_TEMPERATURE_XLSB_REG 0xFC //Temperature XLSB +#define BME280_HUMIDITY_MSB_REG 0xFD //Humidity MSB +#define BME280_HUMIDITY_LSB_REG 0xFE //Humidity LSB + + +//Class SensorSettings. This object is used to hold settings data. The application +//uses this classes' data directly. The settings are adopted and sent to the sensor +//at special times, such as .begin. Some are used for doing math. +// +//This is a kind of bloated way to do this. The trade-off is that the user doesn't +//need to deal with #defines or enums with bizarre names. +// +//A power user would strip out SensorSettings entirely, and send specific read and +//write command directly to the IC. (ST #defines below) +// +struct SensorSettings +{ + public: + + //Main Interface and mode settings + uint8_t commInterface; + uint8_t I2CAddress; + uint8_t chipSelectPin; + + uint8_t runMode; + uint8_t tStandby; + uint8_t filter; + uint8_t tempOverSample; + uint8_t pressOverSample; + uint8_t humidOverSample; + +}; + +//Used to hold the calibration constants. These are used +//by the driver as measurements are being taking +struct SensorCalibration +{ + public: + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; + + uint8_t dig_H1; + int16_t dig_H2; + uint8_t dig_H3; + int16_t dig_H4; + int16_t dig_H5; + uint8_t dig_H6; + +}; + +//This is the man operational class of the driver. + +class BME280 +{ + public: + //settings + SensorSettings settings; + SensorCalibration calibration; + int32_t t_fine; + + //Constructor generates default SensorSettings. + //(over-ride after construction if desired) + BME280( void ); + //~BME280() = default; + + //Call to apply SensorSettings. + //This also gets the SensorCalibration constants + uint8_t begin( void ); + + //Software reset routine + void reset( void ); + + //Returns the values as floats. + float readFloatPressure( void ); + float readFloatAltitudeMeters( void ); + float readFloatAltitudeFeet( void ); + + float readFloatHumidity( void ); + + //Temperature related methods + float readTempC( void ); + float readTempF( void ); + + //The following utilities read and write + + //ReadRegisterRegion takes a uint8 array address as input and reads + //a chunk of memory into that array. + void readRegisterRegion(uint8_t*, uint8_t, uint8_t ); + //readRegister reads one register + uint8_t readRegister(uint8_t); + //Reads two regs, LSByte then MSByte order, and concatenates them + //Used for two-byte reads + int16_t readRegisterInt16( uint8_t offset ); + //Writes a byte; + void writeRegister(uint8_t, uint8_t); + +}; + + + +#endif // End of __BME280_H__ definition check diff --git a/compilation/arduino/userlibs/libraries/escornabot/escornabot.cpp b/compilation/arduino/userlibs/libraries/escornabot/escornabot.cpp new file mode 100644 index 000000000..5fc187442 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/escornabot.cpp @@ -0,0 +1,433 @@ +/* +Librería escornabot por Prudencio Luna y Pedro Ruiz +V 0.20 (04/09/2020): sexta versión, se le pueden colocar sensores como ultrasonidos e infrarrojos. +V 0.15 (16/04/2019): quinta versión, se puede mover los motores mediante procedimiento de medio paso (tipo 3) y se corrigen fallos en constructor con parámetros para elegir modos de paso +V 0.14 (14/04/2019): cuarta versión del programa, cambiado nombre de procedimiento stop por Stop, se arregla procedimiento versión en .h, cambios en procedimiento pushButton, cambios en archivo de ejemplo. +V 0.13 (07/03/2018): tercera versión del programa, incorpora control de motores paso a paso (avances, retrocesos, giros, parada) +, elección del tipo de excitación de bobinas, control de leds, zumbador, botonera y bluetooth. +*/ + +#include "Arduino.h" +#include "escornabot.h" + +// Declaración y asignación de variables privadas + + int step [8][4] =//matriz que describe puesta en marcha de bobinas por defecto (4 posiciones) + { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1} + }; + + int stepsLap=2048;//nº de pasos que da en una vuelta (en paso completo) + int stepsDone=0;//cuenta los pasos dados + int coilPosition=0;// devuelve la posición de la bobina en cada paso (4 posiciones) + int nSteps=4;//numero de pasos que da por ciclo completo + int tstep1rpm=29297;//velocidad en rpm, 29297 es el nº de microsegundos que tardaría en dar 1 paso a 1rpm, 60/2048 y pasarlo a microsegundos + +/*Pinout*/ + const int pinMotor[8]={2,3,4,5,6,7,8,9};//pines de motores + const int buzz = 10; //pin del zumbador + const int led[4] = {14,15,16,17}; // 1 Azul, blue;2 Rojo, red;3 Amarillo, yellow;4 Verde, green + const int pushButtons = A7; //Es una variable analógica. En un circuito paralelo que en función de la tecla que pulsemos obtenemos un valor analógico distinto + +/*Valores aproximados que se obtienen al accionar los pulsadores*/ + int buttonBackward = 768; + int buttonForward = 512; + int buttonRight = 882; + int buttonLeft = 683; + int buttonCenter = 819; + + +/* + escornabot constructor sin pasar parámetros + */ + +escornabot::escornabot() //si no se pasan parámetros al constructor por defecto coge el paso 1 (1 sóla bobina a la vez) +{ +//se inicializa las comunicaciones serie a 9600 baudios (para bluetooth) + Serial.begin (9600);//iniciamos las comunicaciones +//se definen los pines de motores de escornabot como de salida + for (int i=0;i<8;i++) { + pinMode(pinMotor [i],OUTPUT); + } +//se definen los pines de los leds como salida + for(int i=0; i<4; i++){ + pinMode(led[i], OUTPUT); + } +//se define el pin del zumbador como salida + pinMode(buzz, OUTPUT); +// se define el pin analógico de entrada de pulsadores tipo PULL UP + pinMode(pushButtons,INPUT_PULLUP); + +}//escornabot + +/* + escornabot constructor pasando tipo de paso de bobina 1, 2 o 3.( 1 y 2 de paso completo 3 de medio paso) + */ + +escornabot::escornabot(int kindStep) //aquí se construye el objeto escornabot con el tipo de paso (excitación de bobinas) 2 (paso completo con dos bobinas) o 3 (medio paso) +{ +//se inicializa las comunicaciones serie a 9600 baudios (para bluetooth) + Serial.begin (9600);//iniciamos las comunicaciones +//se definen los pines de motores de escornabot como de salida + for (int i=0;i<8;i++) { + pinMode(pinMotor [i],OUTPUT); + } +//se definen los pines de los leds como salida + for(int i=0; i<4; i++){ + pinMode(led[i], OUTPUT); + } +//se define el pin del zumbador como salida + pinMode(buzz, OUTPUT); +// se define el pin analógico de entrada de pulsadores tipo PULL UP + pinMode(pushButtons,INPUT_PULLUP); +//comprueba el parámetro pasado de tipo de paso de bobina + + + if (kindStep==2) {// se excitan dos bobinas a la vez en paso completo (más par más consumo) + /* Ahora la matriz debe cambiar a + {1, 1, 0, 0}, + {0, 1, 1, 0}, + {0, 0, 1, 1}, + {1, 0, 0, 1}*/ + step [0][1] =1;step [1][2]=1;step[2][3]=1;step [3][0]=1;//se cambian los 0 por 1 en la matriz para el paso completo con una bobina por paso + } + + else if (kindStep==3) {//medio paso consumo y par intermedio a los anteriores movimiento más suave + /* Ahora la matriz de medio paso debe cambiar a + {1, 0, 0, 0}, + {1, 1, 0, 0}, + {0, 1, 0, 0}, + {0, 1, 1, 0}, + {0, 0, 1, 0}, + {0, 0, 1, 1}, + {0, 0, 0, 1}, + {1, 0, 0, 1}*/ + step[1][0]=1;step[2][1]=1;step[2][2]=0;//se cambian los 0 por 1 y los 1 por 0 en la matriz para el medio paso + step[3][1]=1;step[3][2]=1;step[3][3]=0; + step[4][2]=1;step[5][2]=1;step[5][3]=1; + step[6][3]=1;step[7][0]=1;step[7][3]=1; + stepsLap=4096; + nSteps=8; + tstep1rpm=14648;//es el nº de microsegundos que tardaría en dar 1 paso a 1rpm, 60/4096 y pasarlo a microsegundos + } +}//escornabot + + +/* +drive procedimiento para avanzar y retroceder +*/ + +void escornabot::drive (float laps, int speed) {//vueltas son el nº de vueltas a dar (+ avanza o - retrocede) y velocidad en rpm + + stepsDone=0; + if (laps>=0) {//si las vueltas son positivas las bobinas se excitan en el sentido de avance + while (int(laps*stepsLap)>=stepsDone) { + stepsDone ++; + coilPosition=stepsDone % nSteps;//calcula el resto para saber en la posición de bobina que está + //cuando un pin está en una fila de la matriz el del otro motor está a la inversa pin 2 col 4 pin 6 col 1 por ejemplo + digitalWrite(pinMotor[0], step[coilPosition][3]);//pin 2 + digitalWrite(pinMotor[4], step[coilPosition][0]);//pin 6 + digitalWrite(pinMotor[1], step[coilPosition][2]);//pin 3 + digitalWrite(pinMotor[5], step[coilPosition][1]);//pin 7 + digitalWrite(pinMotor[2], step[coilPosition][1]);//pin 4 + digitalWrite(pinMotor[6], step[coilPosition][2]);//pin 8 + digitalWrite(pinMotor[3], step[coilPosition][0]);//pin 5 + digitalWrite(pinMotor[7], step[coilPosition][3]);//pin 9 + delayMicroseconds(tstep1rpm/speed); + } + } + + else {//si las vueltas son negativas las bobinas se excitan en el sentido de retroceso + while (int(-laps*stepsLap)>=stepsDone) { + stepsDone ++; + coilPosition=stepsDone % nSteps; + digitalWrite(pinMotor[0], step[coilPosition][0]); + digitalWrite(pinMotor[4], step[coilPosition][3]); + digitalWrite(pinMotor[1], step[coilPosition][1]); + digitalWrite(pinMotor[5], step[coilPosition][2]); + digitalWrite(pinMotor[2], step[coilPosition][2]); + digitalWrite(pinMotor[6], step[coilPosition][1]); + digitalWrite(pinMotor[3], step[coilPosition][3]); + digitalWrite(pinMotor[7], step[coilPosition][0]); + delayMicroseconds(tstep1rpm/speed); + } + + } + +}//drive + +/* +driveD procedimiento para avanzar y retroceder +*/ + +void escornabot::driveD (float distance, int speed) {//distancia es el nº de cm a avanzar (+ avanza o - retrocede) y velocidad en rpm + escornabot::drive ((distance/24.19),speed); + +}//driveD + + +/* +stop procedimiento de paro de los motores + */ + +void escornabot::Stop () { + + for (int i=0; i<8; i++) { + digitalWrite (pinMotor[i],LOW); + } + +}//stop + +/* +turn procedimiento para girar con vueltas +*/ + +void escornabot::turn (float laps, int speed) {//laps son el nº de vueltas a girar (+ en un sentido o - en el otro) y speed en rpm + + stepsDone=0; + if (laps>=0) {//si las vueltas son positivas provoca giro a la derecha moviendo rueda izquierda adelante y derecha atrás + while (int(laps*stepsLap)>=stepsDone) { + stepsDone ++; + coilPosition=stepsDone % nSteps; + digitalWrite(pinMotor[0], step[coilPosition][0]); + digitalWrite(pinMotor[4], step[coilPosition][0]); + digitalWrite(pinMotor[1], step[coilPosition][1]); + digitalWrite(pinMotor[5], step[coilPosition][1]); + digitalWrite(pinMotor[2], step[coilPosition][2]); + digitalWrite(pinMotor[6], step[coilPosition][2]); + digitalWrite(pinMotor[3], step[coilPosition][3]); + digitalWrite(pinMotor[7], step[coilPosition][3]); + delayMicroseconds(tstep1rpm/speed); + } + + } + + else {//si las vueltas son negativas provoca giro a la izquierda moviendo rueda derecha adelante e izquierda atrás + while (int(-laps*stepsLap)>=stepsDone) { + stepsDone ++; + coilPosition=stepsDone % nSteps; + digitalWrite(pinMotor[0], step[coilPosition][3]); + digitalWrite(pinMotor[4], step[coilPosition][3]); + digitalWrite(pinMotor[1], step[coilPosition][2]); + digitalWrite(pinMotor[5], step[coilPosition][2]); + digitalWrite(pinMotor[2], step[coilPosition][1]); + digitalWrite(pinMotor[6], step[coilPosition][1]); + digitalWrite(pinMotor[3], step[coilPosition][0]); + digitalWrite(pinMotor[7], step[coilPosition][0]); + delayMicroseconds(tstep1rpm/speed); + } + + } + +}//turn + +/* +turnA procedimiento para girar con angulo +*/ + +void escornabot::turnA (float angle, int speed) {//angle son el nº de grados a girar (+ en un sentido o - en el otro) y speed en rpm + + escornabot::turn (angle/360,speed); +}//turnA + +/* + *ledON procedimiento para encender leds + * */ +void escornabot::ledON(int ledNumber){ + digitalWrite(led[ledNumber-1], HIGH); +}//ledON + +/* + * ledOFF procedimiento para apagar leds + * */ +void escornabot::ledOFF(int ledNumber){ + digitalWrite(led[ledNumber-1], LOW); +}//ledOFF + +/* +* ledState procedimiento para ver el estado del led ledNumber +*/ +int escornabot::ledState(int ledNumber){ + return digitalRead(led[ledNumber-1]); +} + +/* + * buzzON procedimiento para encender zumbador + * */ +void escornabot::buzzON(){ + digitalWrite(buzz,HIGH); +}//buzzON + +/* + * buzzOFF procedimiento para apagar zumbador + * */ +void escornabot::buzzOFF(){ + digitalWrite(buzz,LOW); +}//buzOFF + +/* + * pushButton procedimiento para determinar el pulsador pulsado + * */ +int escornabot::pushButton(){ + int value=0; + if(analogRead(pushButtons)>=748 && analogRead(pushButtons)<=788) {//atras + value=3; + //delay(200); + } + else if(analogRead(pushButtons)>=492 && analogRead(pushButtons)<=532) {//adelante + value=1; + //delay(200); + } + else if(analogRead(pushButtons)>=862 && analogRead(pushButtons)<=902) {//derecha + value=4; + //delay(200); + } + else if(analogRead(pushButtons)>=663 && analogRead(pushButtons)<=703) {//izquierda + value=2; + //delay(200); + } + else if(analogRead(pushButtons)>=799 && analogRead(pushButtons)<=839) {//centro + value=5; + //delay(200); + } + else { + value=0; + } + + return value; +}//pushButton + +/* + * blueT procedimiento para saber el caracter que me han mandado por Bluetooth + * */ +int escornabot::blueT(){ + if (Serial.available()>0) { + int dato=Serial.read(); + return dato; + } + else return 0; +}//blueT + +/* + version() procedimiento que devuelve la versión de la librería +*/ +float escornabot::version(){ + return 0.20; +} + +//A propuesta de Antonio Gómez + +/* +infrared procedimiento que configura los pines de los sensores infrarrojos +*/ +void escornabot::infrared(int izq, int der){ + _IRL=izq; + _IRR=der; + pinMode(_IRL,INPUT); + pinMode(_IRR,INPUT); +} + +/* +us procedimiento que configura los pines del sensor de ultrasonidos +*/ +void escornabot::us(int trig, int echo){ + _trig=trig; + _echo=echo; + pinMode(_trig,OUTPUT); + pinMode(_echo,INPUT); +} + + +/* +distance() procedimiento que devuelve la distancia en cm del sensor de ultrasonidos +*/ +long escornabot::distance(){ + + long espacio; + long tiempo; + digitalWrite(_trig,LOW); + delayMicroseconds(4); + digitalWrite(_trig,HIGH); + delayMicroseconds(10); + digitalWrite(_trig,LOW); + tiempo=pulseIn(_echo,HIGH); + espacio=tiempo/58.309037901; + return espacio; +} + +/* +blackRight procedimiento que nos devuelve true o false si el sensor de ir derecho está a negro +*/ +bool escornabot::blackRight(){ + bool negro; + if (digitalRead(_IRR)==1){ + negro=true; + } + else{ + negro=false; + } + return negro; +} + +/* +blackLeft procedimiento que nos devuelve true o false si el sensor de ir izquierdo está a negro +*/ +bool escornabot::blackLeft(){ + bool negro; + if (digitalRead(_IRL)==1){ + negro=true; + } + else{ + negro=false; + } + return negro; +} + +/* +whiteRight procedimiento que nos devuelve true o false si el sensor de ir derecho está a blanco +*/ +bool escornabot::whiteRight(){ + bool blanco; + if (digitalRead(_IRR)==1){ + blanco=false; + } + else{ + blanco=true; + } + return blanco; +} + + +/* +whiteLeft procedimiento que nos devuelve true o false si el sensor de ir izquierdo está a blanco +*/ +bool escornabot::whiteLeft(){ + bool blanco; + if (digitalRead(_IRL)==1){ + blanco=false; + } + else{ + blanco=true; + } + return blanco; +} + +/* +buzzer procedimiento para indicar el pin al que se conecta un zumbador +*/ +void escornabot::buzzer(int pin){ + _buzz=pin; + pinMode(_buzz,OUTPUT); +} + +/* +tono procedimiento para indicar la frecuencia y duración del sonido del zumbador +*/ +void escornabot::tono(int frequency, int time){ + tone(_buzz, frequency,time); + delay(time); + noTone(_buzz); +} diff --git a/compilation/arduino/userlibs/libraries/escornabot/escornabot.h b/compilation/arduino/userlibs/libraries/escornabot/escornabot.h new file mode 100644 index 000000000..7031a90d8 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/escornabot.h @@ -0,0 +1,81 @@ +/* +Librería escornabot por Prudencio Luna y Pedro Ruiz +V 0.20 (04/09/2020): sexta versión, se le pueden colocar sensores como ultrasonidos e infrarrojos. +V 0.15 (16/04/2019): quinta versión, se puede mover los motores mediante procedimiento de medio paso (tipo 3) y se corrigen fallos en constructor con parámetros para elegir modos de paso. +V 0.14 (14/04/2019): cuarta versión del programa, cambiado nombre de procedimiento stop por Stop, se arregla procedimineto versión en .h, cambios en procedimiento pushButton, cambios en archivo de ejemplo. +V 0.13 (07/03/2018): tercera versión del programa, incorpora control de motores paso a paso (avances, retrocesos, giros, parada) +, elección del tipo de excitación de bobinas, control de leds, zumbador, botonera y bluetooth. +*/ + +#ifndef escornabot_h +#define escornabot_h + +enum buttonLed {forward=1,left=2,backward=3,right=4,central=5}; + +// Descripción de la clase Escornabot +class escornabot { + //Definición de elementos públicos + public: + // constructor: + escornabot();//sin pasar parámetros + escornabot(int kindStep);// pasa el tipo de paso 1 (un sola bobina a la vez), paso 2 (dos bobinas a la vez) + + const static int numberButtons=5; + const static int numberLeds=5; + + // procedimiento para mover los motores: + void drive (float laps, int speed); + //procedimiento para mover los motores por distancia + void driveD (float distance, int speed); + //procemiento para girar con vueltas: + void turn (float laps, int speed); + //procedimiento para girar con ańgulo: + void turnA (float angle, int speed); + // procedimiento para parar: + void Stop(); + //procedimiento para encender y apagar leds, y saber estado + void ledON(int ledNumber); + void ledOFF(int ledNumber); + int ledState(int ledNumber); + //procedimiento para encender y apagar el zumbador + void buzzON(); + void buzzOFF(); + //procedimiento para saber el botón que se ha pulsado + int pushButton(); + //procedimiento que devuelve valor enviado por bluetooth + int blueT(); + //procedimiento que devuelve la versión de la librería + float version(); + + //A propuesta de Antonio Gómez + //procedimiento que configura los pines de los sensores infrarrojos + void infrared(int izq,int der); + //procedimiento que configura los pines del sensor de ultrasonidos + void us(int trig, int echo); + //procedimiento que devuelve la distancia en cm del sensor de ultrasonidos + long distance(); + //procedimiento que nos devuelve true o false si el sensor de ir derecho está a negro + bool blackRight(); + //procedimiento que nos devuelve true o false si el sensor de ir izquierdo está a negro + bool blackLeft(); + //procedimiento que nos devuelve true o false si el sensor de ir derecho está a blanco + bool whiteRight(); + //procedimiento que nos devuelve true o false si el sensor de ir izquierdo está a blanco + bool whiteLeft(); + //procedimiento para indicar el pin al que se conecta un zumbador + void buzzer(int pin); + //procedimiento para indicar la frecuencia y duración del sonido del zumbador + void tono(int frequency, int time); + + //Definición de elementos privados + private: +int _trig; +int _echo; +int _IRR; +int _IRL; +int _buzz; + + protected: +}; + +#endif //escornabot_h diff --git a/compilation/arduino/userlibs/libraries/escornabot/examples/buzzer/buzzer.ino b/compilation/arduino/userlibs/libraries/escornabot/examples/buzzer/buzzer.ino new file mode 100644 index 000000000..51ed494d9 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/examples/buzzer/buzzer.ino @@ -0,0 +1,20 @@ +#include + +escornabot miescorni; + +void setup() { + + miescorni.buzzer(10); + +} + +void loop() { + + for (int x = 0; x < 1000; x = x + 100) { + miescorni.tono(x, 500); + } + + for (int x = 1000; x >=0; x = x - 100) { + miescorni.tono(x, 500); + } +} diff --git a/compilation/arduino/userlibs/libraries/escornabot/examples/line_follower/line_follower.ino b/compilation/arduino/userlibs/libraries/escornabot/examples/line_follower/line_follower.ino new file mode 100644 index 000000000..ae73052a3 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/examples/line_follower/line_follower.ino @@ -0,0 +1,45 @@ +#include + +escornabot miescorni; +boolean funciona = false; + +void setup() { + //Serial.begin(9600); + miescorni.infrared(11,12); + +} + +void loop() { + + compruebaBoton(); + + if (funciona == true) { + + if (miescorni.blackRight() && miescorni.whiteLeft()) {//si sensor izquierdo encuentra blanco + miescorni.turnA(-5, 10);//gira hacia la derecha en el sentido contrario a la marcha + } + if (miescorni.whiteRight() && miescorni.blackLeft()) {//si sensor derecho encuentra blanco + miescorni.turnA(5, 10);//gira hacia la izquierda en el sentido contrario a la marcha + } + + if (miescorni.blackRight() && miescorni.blackLeft()) {//si los dos sensores encuentran negro + miescorni.driveD(-2, 13);//se mueve hacia delante en el sentido contrario a la marcha + } + if (miescorni.whiteRight() && miescorni.whiteLeft()) {//si los dos sensores encuentran blanco + miescorni.driveD(2, 13);//se mueve hacia detrás en el sentido contrario a la marcha + } + + } + + else if (funciona == false) { + miescorni.Stop(); + } + +} + +void compruebaBoton () { + if (miescorni.pushButton() == right) { + funciona = !funciona; + delay (300); + } +} diff --git a/compilation/arduino/userlibs/libraries/escornabot/examples/test_escornabot/test_escornabot.ino b/compilation/arduino/userlibs/libraries/escornabot/examples/test_escornabot/test_escornabot.ino new file mode 100644 index 000000000..a469dac5b --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/examples/test_escornabot/test_escornabot.ino @@ -0,0 +1,138 @@ +#include + +escornabot mirobot;//por defecto funciona a modo paso completo con activación de una sóla bobina en cada paso (menor consumo y menor par) +// si ponemos mirobot(2), se activa el modo paso completo con activación de dos bobinas a la vez en cada paso (mayor consumo y mayor par) +// si ponemos mirobot(3), se activa el modo medio paso (consumo y par intermedio con los casos anteriores y movimiento más suave) + +boolean led1 = false; +boolean led2 = false; +boolean led3 = false; +boolean led4 = false; +boolean buzz = false; + +void setup() { + Serial.begin (9600); +} + +void loop() { + //prueba de librería + + switch (mirobot.pushButton()) { + + case forward://si pulsamos el botón delantero, se enciende led delantero, se mueve 8 cm hacia delante, y se apaga el led delantero + mirobot.ledON (forward); + mirobot.driveD (8, 10); + mirobot.ledOFF (forward); + break; + + case backward://si pulsamos el botón trasero, se enciende led trasero, se mueve 8 cm hacia atrás, y se apaga el led trasero + mirobot.ledON (backward); + mirobot.driveD (-8, 10); + mirobot.ledOFF (backward); + break; + + case right://si pulsamos el botón derecho, se enciende led derecho, gira 45 grados hacia la derecha, y se apaga el led derecho + mirobot.ledON (right); + mirobot.turnA (45, 10); + mirobot.ledOFF (right); + break; + + case left://si pulsamos el botón izquierdo, se enciende led izquierdo, se mueve 45 grados hacia la izquierda, y se apaga el led izquierdo + mirobot.ledON (left); + mirobot.turnA (-45, 10); + mirobot.ledOFF (left); + break; + + case central://si pulsamos el botón central, suena el zumbador y se enciende todos los leds durante un segundo, después se apagan el zumbador y los leds + mirobot.buzzON (); + for (int i = 1; i < mirobot.numberLeds; i++) + { + mirobot.ledON(i); + } + delay (1000); + mirobot.buzzOFF(); + + for (int i = 1; i < mirobot.numberLeds; i++) + { + mirobot.ledOFF(i); + } + break; + + default://otro caso, si no pulsamos nada, no se mueve el robot + mirobot.driveD (0,0); + break; + + } + + switch (mirobot.blueT()) {//en función del caracter emitido por bluetooth hace varias acciones + case 'A': + mirobot.drive (0.25, 12); + break; + case 'R': + mirobot.drive (-0.25, 12); + break; + case 'D': + mirobot.turn (0.125, 12); + break; + case 'I': + mirobot.turn (-0.125, 12); + break; + case '1': + /*led1 = !led1; + if (led1) { + mirobot.ledON(forward); + } + else { + mirobot.ledOFF(forward); + }*/ + invierteLed(forward); + break; + case '2': + led2 = !led2; + if (led2) { + mirobot.ledON(left); + } + else { + mirobot.ledOFF(left); + } + break; + case '3': + led3 = !led3; + if (led3) { + mirobot.ledON(backward); + } + else { + mirobot.ledOFF(backward); + } + break; + case '4': + led4 = !led4; + if (led4) { + mirobot.ledON(right); + } + else { + mirobot.ledOFF(right); + } + break; + case '5': + buzz = !buzz; + if (buzz) { + mirobot.buzzON(); + } + else { + mirobot.buzzOFF(); + } + break; + //default: + // statements + } + +} + +void invierteLed(int i) { + if (mirobot.ledState(i)) { + mirobot.ledOFF(i); + } else { + mirobot.ledON(i); + } +} diff --git a/compilation/arduino/userlibs/libraries/escornabot/examples/us/us.ino b/compilation/arduino/userlibs/libraries/escornabot/examples/us/us.ino new file mode 100644 index 000000000..2a715bced --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/examples/us/us.ino @@ -0,0 +1,41 @@ +#include + +escornabot mirobot; + +boolean funciona = false; + +void setup() { + mirobot.us(11, 12); //configuramos los pines trigger y echo +} + +void loop() { + + compruebaBoton(); + + if (funciona == true) { + + + mirobot.driveD(-5, 10); + + if (mirobot.distance() <= 15) { + + mirobot.driveD (5, 10); + mirobot.turnA (-45, 10); + + } + + + } + + else if (funciona == false) { + mirobot.Stop(); + } + +} + +void compruebaBoton () { + if (mirobot.pushButton() == right) { + funciona = !funciona; + delay (300); + } +} diff --git a/compilation/arduino/userlibs/libraries/escornabot/keywords.txt b/compilation/arduino/userlibs/libraries/escornabot/keywords.txt new file mode 100644 index 000000000..cc66af700 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/keywords.txt @@ -0,0 +1,34 @@ +####################################### +# Syntax Coloring Map For Escornabot +####################################### +# Class +####################################### + +escornabot KEYWORD1 + +####################################### +# Methods and Functions +####################################### + +drive KEYWORD2 +driveD KEYWORD2 +turn KEYWORD2 +turnA KEYWORD2 +Stop KEYWORD2 +ledON KEYWORD2 +ledOFF KEYWORD2 +ledState KEYWORD2 +buzzON KEYWORD2 +buzzOFF KEYWORD2 +pushButton KEYWORD2 +blueT KEYWORD2 +version KEYWORD2 +infrared KEYWORD2 +blackRight KEYWORD2 +blackLeft KEYWORD2 +whiteRight KEYWORD2 +whiteLeft KEYWORD2 +us KEYWORD2 +distance KEYWORD2 +buzzer KEYWORD2 +tono KEYWORD2 diff --git a/compilation/arduino/userlibs/libraries/escornabot/library.properties b/compilation/arduino/userlibs/libraries/escornabot/library.properties new file mode 100644 index 000000000..a21aeb4d2 --- /dev/null +++ b/compilation/arduino/userlibs/libraries/escornabot/library.properties @@ -0,0 +1,9 @@ +name=escornabot +version=0.2.0 +author=Prudencio Luna, Pedro Ruiz, Antonio Gómez +maintainer= +sentence=Arduino library for control of the Escornabot robot +paragraph= +category=Device Control +url=https://github.com/escornabot/libreria-arduino +architectures=* diff --git a/www/blocs&generateurs/matrix.js b/www/blocs&generateurs/matrix.js index 185bd2f3e..a165982d3 100644 --- a/www/blocs&generateurs/matrix.js +++ b/www/blocs&generateurs/matrix.js @@ -14,8 +14,11 @@ Blockly.Blocks['GFX_matrix_init'] = { init: function() { }; Blockly.Arduino['GFX_matrix_init'] = function(block) { Blockly.Arduino.includes_['matrix16x8'] = -'#include "HT16K33_GFX.h""\n' -+'HT16K33_GFX matrixGXF1 = HT16K33_GFX(MATRIX_COUNT, 0x70);'; +'#include "HT16K33_GFX.h"\n' ++'#define MATRIX_COUNT 2 // // Number of simulated matrices or OLED screen (1 to 4)\n' ++'#define MATRIX_ROTATION 3 // // Rotation from 0 to 3\n' ++'#define OLED_RESET -1 // sharing Arduino reset pin\n' ++'HT16K33_GFX matrix = HT16K33_GFX(MATRIX_COUNT, 0x70);'; Blockly.Arduino.variables_['matrix16x8'] = 'static const uint8_t PROGMEM robot[] = {B01111110,B10000001,B10100101,B10000001,B01111110,B10000001,B10000001,B10000001},\n' +'mouse[] = {B01000010,B10111101,B10000001,B10100101,B10000001,B01000010,B00100100,B00011000}, \n' @@ -23,14 +26,9 @@ Blockly.Arduino.variables_['matrix16x8'] = +'bat[] = {B10000001,B11000011,B10111101,B10000001,B10100101,B10000001,B01011010,B00100100},\n' +'robot2[] = {B01111110,B11110001,B11010101,B11110001,B01111110,B10001111,B10001111,B10001111};\n' +'const static char scrollString[] PROGMEM = "I CAN SCROLL TEXT and Do SOMEThing else !";'; -Blockly.Arduino.definitions_['matrix16x8'] = -'#define MATRIX_COUNT 1 // // Number of simulated matrices or OLED screen (1 to 4)\n' -+'#define MATRIX_ROTATION 3 // // Rotation from 0 to 3\n' -+'#define OLED_RESET -1 // sharing Arduino reset pin\n' -+'Adafruit_SH1106 display(OLED_RESET);'; Blockly.Arduino.setups_['matrix16x8']= - 'Wire.begin();\n'; -+'matrix.setRotation(MATRIX_ROTATION);\n'; + 'Wire.begin();\n' ++'matrix.setRotation(MATRIX_ROTATION);\n' +'matrix.init();\n'; var code=''; return code; @@ -39,12 +37,8 @@ return code; Blockly.Blocks['GFX_OLED_init'] = { init: function() { - this.appendDummyInput() - .appendField(new Blockly.FieldImage('media/oled.png', 33, 33, "*")) - .appendField("OLED 1.3'' Pins I²C") - this.appendDummyInput() - .setAlign(Blockly.ALIGN_RIGHT) - .appendField(new Blockly.FieldDropdown([["0x3C", "0x3C"], ["0x3D", "0x3D"], ["0x7A", "0x7A"], ["0x7B", "0x7B"]]), "address"); + this.appendDummyInput() .appendField(new Blockly.FieldImage('media/oled.png', 33, 33, "*")).appendField("OLED 0.96'' Pins I²C") + this.appendDummyInput().setAlign(Blockly.ALIGN_RIGHT).appendField(new Blockly.FieldDropdown([["0x3C", "0x3C"], ["0x3D", "0x3D"], ["0x7A", "0x7A"], ["0x7B", "0x7B"]]), "address"); this.setInputsInline(true); this.setPreviousStatement(true); this.setNextStatement(true); @@ -57,7 +51,9 @@ Blockly.Blocks['GFX_OLED_init'] = { var value_address = block.getFieldValue('address'); Blockly.Arduino.includes_['OLED'] = '#include \n' - +'OLED_GFX matrixGXF2 = OLED_GFX(0x3C, OLED_12864, MATRIX_COUNT, false, false);'; + +'#define MATRIX_COUNT 2 // // Number of simulated matrices or OLED screen (1 to 4)\n' + +'#define MATRIX_ROTATION 3 // // Rotation from 0 to 3\n' + +'OLED_GFX matrixGXF2 = OLED_GFX('+value_address+', OLED_12864, MATRIX_COUNT, flase, false);'; Blockly.Arduino.variables_['matrix16x8'] = 'static const uint8_t PROGMEM robot[] = {B01111110,B10000001,B10100101,B10000001,B01111110,B10000001,B10000001,B10000001},\n' +'mouse[] = {B01000010,B10111101,B10000001,B10100101,B10000001,B01000010,B00100100,B00011000}, \n' @@ -65,11 +61,39 @@ Blockly.Blocks['GFX_OLED_init'] = { +'bat[] = {B10000001,B11000011,B10111101,B10000001,B10100101,B10000001,B01011010,B00100100},\n' +'robot2[] = {B01111110,B11110001,B11010101,B11110001,B01111110,B10001111,B10001111,B10001111};\n' +'const static char scrollString[] PROGMEM = "I CAN SCROLL TEXT and Do SOMEThing else !";'; - Blockly.Arduino.definitions_['matrix16x8'] = - '#define MATRIX_COUNT 1 // // Number of simulated matrices or OLED screen (1 to 4)\n' + Blockly.Arduino.setups_['matrix16x8']= + 'Wire.begin();\n'; + +'matrix.setRotation(MATRIX_ROTATION);\n'; + +'matrix.init();\n'; + return "" +}; + +Blockly.Blocks['GFX_OLED_init2'] = { + init: function() { + this.appendDummyInput() .appendField(new Blockly.FieldImage('media/oled.png', 33, 33, "*")).appendField("OLED 1.3'' Pins I²C") + this.appendDummyInput().setAlign(Blockly.ALIGN_RIGHT).appendField(new Blockly.FieldDropdown([["0x3C", "0x3C"], ["0x3D", "0x3D"], ["0x7A", "0x7A"], ["0x7B", "0x7B"]]), "address"); + this.setInputsInline(true); + this.setPreviousStatement(true); + this.setNextStatement(true); + this.setColour("#4b009f"); + this.setTooltip(''); + this.setHelpUrl('https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples'); + } + }; + Blockly.Arduino['GFX_OLED_init2'] = function(block) { + var value_address = block.getFieldValue('address'); + Blockly.Arduino.includes_['OLED'] = + '#include \n' + +'#define MATRIX_COUNT 2 // // Number of simulated matrices or OLED screen (1 to 4)\n' +'#define MATRIX_ROTATION 3 // // Rotation from 0 to 3\n' - +'#define OLED_RESET -1 // sharing Arduino reset pin\n' - +'Adafruit_SH1106 display(OLED_RESET);'; + +'OLED_GFX matrixGXF2 = OLED_GFX('+value_address+', OLED_12864, MATRIX_COUNT, true, false);'; + Blockly.Arduino.variables_['matrix16x8'] = + 'static const uint8_t PROGMEM robot[] = {B01111110,B10000001,B10100101,B10000001,B01111110,B10000001,B10000001,B10000001},\n' + +'mouse[] = {B01000010,B10111101,B10000001,B10100101,B10000001,B01000010,B00100100,B00011000}, \n' + +'reindeer[] = {B01000010,B11100111,B01000010,B00000000,B00100100,B00000000,B00000000,B00011000},\n' + +'bat[] = {B10000001,B11000011,B10111101,B10000001,B10100101,B10000001,B01011010,B00100100},\n' + +'robot2[] = {B01111110,B11110001,B11010101,B11110001,B01111110,B10001111,B10001111,B10001111};\n' + +'const static char scrollString[] PROGMEM = "I CAN SCROLL TEXT and Do SOMEThing else !";'; Blockly.Arduino.setups_['matrix16x8']= 'Wire.begin();\n'; +'matrix.setRotation(MATRIX_ROTATION);\n'; @@ -78,7 +102,7 @@ Blockly.Blocks['GFX_OLED_init'] = { }; Blockly.Blocks['GFX_display'] = {init: function() { - this.appendDummyInput() .appendField("👀 "+Blockly.Msg.LCD_SHIELD_PRINT_TEXT); + this.appendDummyInput() .appendField("🔆 "+Blockly.Msg.LCD_SHIELD_PRINT_TEXT); this.setInputsInline(false); this.setPreviousStatement(true); this.setNextStatement(true); @@ -107,7 +131,7 @@ return code; Blockly.Blocks['GFX_pixel']={ init:function(){ Blockly.FieldCheckbox.CHECK_CHAR= '▉' - this.appendDummyInput() .appendField("👀 . X") + this.appendDummyInput() .appendField("🔆 . X") this.appendValueInput("X") .setCheck("Number") this.appendValueInput("Y") .setCheck("Number").appendField("Y"); this.appendDummyInput() .appendField("✏️") .appendField(new Blockly.FieldCheckbox("TRUE"), "draw"); @@ -125,12 +149,12 @@ Blockly.Arduino['GFX_pixel'] = function(block) { if(this.getFieldValue('draw') == 'TRUE') draw= "GFX_WHITE"; else draw = "GFX_BLACK"; var code = - 'void drawPixel('+valuex+','+valuey+','+draw+');\n'; + 'matrix.drawPixel('+valuex+','+valuey+','+draw+');\n'; return code; }; Blockly.Blocks['GFX_line']={ init:function(){ - this.appendDummyInput() .appendField("👀 _ X1") + this.appendDummyInput() .appendField("🔆 _ X1") this.appendValueInput("X1") .setCheck("Number") this.appendValueInput("Y1") .setCheck("Number").appendField("Y1"); this.appendValueInput("X2") .setCheck("Number").appendField("X2"); @@ -158,7 +182,7 @@ Blockly.Arduino['GFX_line'] = function(block) { Blockly.Blocks['GFX_rectangle']={ init:function(){ Blockly.FieldCheckbox.CHECK_CHAR= '▉' - this.appendDummyInput() .appendField("👀 🔲 X1") + this.appendDummyInput() .appendField("🔆 🔲 X1") this.appendValueInput("X1") .setCheck("Number") this.appendValueInput("Y1") .setCheck("Number").appendField("Y1"); this.appendValueInput("X2") .setCheck("Number").appendField("X2"); @@ -187,7 +211,7 @@ Blockly.Arduino['GFX_rectangle'] = function(block) { Blockly.Blocks['GFX_circle']={ init:function(){ Blockly.FieldCheckbox.CHECK_CHAR= '▉' - this.appendDummyInput() .appendField("👀 ⚪ X") + this.appendDummyInput() .appendField("🔆 ⚪ X") this.appendValueInput("X") .setCheck("Number") this.appendValueInput("Y") .setCheck("Number").appendField("Y"); this.appendValueInput("R") .setCheck("Number").appendField("R"); @@ -215,7 +239,7 @@ Blockly.Arduino['GFX_circle'] = function(block) { Blockly.Blocks['GFX_bitmap'] = { init: function() { this.setColour("#4b009f"); - this.appendDummyInput().appendField("🖥️").appendField(Blockly.Msg.OLED_DrawiconName) + this.appendDummyInput().appendField("🔆").appendField(Blockly.Msg.OLED_DrawiconName) this.appendDummyInput().appendField(new Blockly.FieldTextInput("IconName"), "NAME"); this.appendValueInput("x0").setCheck("Number").appendField(Blockly.Msg.OLED_X0); this.appendValueInput("y0").setCheck("Number").appendField(Blockly.Msg.OLED_Y0); @@ -245,7 +269,7 @@ Blockly.Arduino['GFX_bitmap'] = function(block) { else draw = "GFX_BLACK"; var code = - 'matrix.drawBitmap(('+x0+','+y0+','+IconName+','+width+','+height+',true,'+draw+',GFX_BLACK);\n'; + 'matrix.drawBitmap('+x0+','+y0+','+IconName+','+width+','+height+',true,'+draw+',GFX_BLACK);\n'; return code; }; diff --git a/www/examples/examples.json b/www/examples/examples.json index b93d7967a..2d9dead0a 100644 --- a/www/examples/examples.json +++ b/www/examples/examples.json @@ -1,70 +1,72 @@ [ - {"source_url": "servo.xml","source_text": "👶Level 1 | 🦿 Servo centering | Starter","visible": true}, - {"source_url": "servosweep.xml","source_text": "👶Level 1 | 🦿 Servo Sweep | Starter","visible": true}, - {"source_url": "Ottocalibration.xml","source_text": "👶Level 1 | 🤖 Basic calibration | Starter","visible": true }, - {"source_url": "Ottocalibrationapp.xml","source_text": "👶Level 1 | 🤖 Proper calibration with App | Starter","visible": true }, - {"source_url": "Ottobuzzer.xml","source_text": "👶Level 1 | 🔈 Otto sounds | Starter ","visible": true}, - {"source_url": "melody.xml","source_text": "👶Level 1 | 🎼 Melody | Starter ","visible": true}, - {"source_url": "RTTL.xml","source_text": "👶Level 1 | 🎼 Ring Tone sounds | Starter ","visible": true}, - {"source_url": "Ottowalk.xml", "source_text": "👶Level 1 | 🤖 Walk | Starter", "visible": true }, - {"source_url": "Ottodance.xml","source_text": "👶Level 1 | 🤖 Dance | Starter","visible": true}, - {"source_url": "Ottodancerandom.xml","source_text": "👶Level 1 | 🤖 Random Dancer | Starter","visible": true}, - {"source_url": "Ottoavoid.xml","source_text": "👶Level 1 | 🤖 Avoid obstacles | Starter","visible": true}, - {"source_url": "Ottoavoidpeople.xml","source_text": "👶Level 1 | 🤖 Avoid People | Starter","visible": true}, - {"source_url": "Ottofollow.xml","source_text": "👶Level 1 | 🌌 The force is with you | Starter","visible": true}, - {"source_url": "theremin.xml","source_text": "👶Level 1 | 🎹 Theremin | Starter ","visible": true}, - {"source_url": "wheelsavoid.xml","source_text": "👶Level 1 | 🚗 Wheels Avoid | Wheels","visible": true}, - {"source_url": "serialdistance.xml","source_text": "👨‍💻Level 2 | 📏 Serial measure distance | Starter","visible": true }, - {"source_url": "touch.xml","source_text": "👨‍💻Level 2 | 👇 Touch interaction | +sensor","visible": true}, - {"source_url": "noise.xml","source_text": "👨‍💻Level 2 | 👏 Sound interaction | +sensor","visible": true}, - {"source_url": "serialnoise.xml","source_text": "👨‍💻Level 2 | 👏 Serial noise readings | +sensor","visible": true }, - {"source_url": "touchsoundtest.xml","source_text": "👨‍💻Level 2 | 👇 Touch & 👏Noise sensor test | +sensor","visible": true}, - {"source_url": "touchsoundultra.xml","source_text": "👨‍💻Level 2 | 👇 Avoid, touch & noise | +sensor","visible": true}, - {"source_url": "matrixtest.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED Matrix Test | +mouth","visible": true }, - {"source_url": "matrixmouths.xml","source_text": "👨‍💻Level 2 | 👄 Mouths Emotions | +mouth","visible": true }, - {"source_url": "matrixmouthspeech.xml","source_text": "👨‍💻Level 2 | 👄 Mouths Speak | +mouth","visible": true }, - {"source_url": "matrixsing.xml","source_text": "👨‍💻Level 2 | 👄 Mouths Sing | +mouth","visible": true }, - {"source_url": "matrixcounter.xml","source_text": "👨‍💻Level 2 | 👄 Variable counter | +mouth","visible": true}, - {"source_url": "matrixhands.xml","source_text": "👨‍💻Level 2 | 🧼 Clean you hands | +mouth","visible": true}, - {"source_url": "matrixeyestest.xml","source_text": "👨‍💻Level 2 | 👀 16x8 LED Matrix Test | +eyes","visible": true }, - {"source_url": "matrixeyes.xml","source_text": "👨‍💻Level 2 | 👀 Eyes Emotions | +eyes","visible": true}, - {"source_url": "ledfade.xml","source_text": "👨‍💻Level 2 | 💡 Single LED Fade | +LED","visible": true }, - {"source_url": "ledpot.xml","source_text": "👨‍💻Level 2 | 💡 Single LED Potentiometer | +LED","visible": true }, - {"source_url": "ledfadepot.xml","source_text": "👨‍💻Level 2 | 💡 Single LED Potentiometer Fade | +LED","visible": true }, - {"source_url": "servoadvanced.xml","source_text": "👨‍💻Level 2 | 🦿 Servo Advanced | Starter","visible": true}, - {"source_url": "irda.xml","source_text": "👨‍💻Level 2 | 🎮 Remote control | + infrared","visible": true}, - {"source_url": "ottoky.xml","source_text": "👨‍🚀Level 3 | 👓 Ottoky happy | Ottoky","visible": true }, - {"source_url": "ottokysense.xml","source_text": "👨‍🚀Level 3 | 🎛️ Ottoky sense | Ottoky","visible": true }, - {"source_url": "ottokyiotclock.xml","source_text": "👨‍🚀Level 3 | 🌐 Ottoky clock | Ottoky","visible": true }, - {"source_url": "ottokyavoid.xml","source_text": "👨‍🚀Level 3 | 🧠 Ottoky avoid | Ottoky","visible": true }, - {"source_url": "ottokydht.xml","source_text": "👨‍🚀Level 3 | 🌡️ Ottoky Temperature | Ottoky","visible": true }, - {"source_url": "neopixel.xml", "source_text": "👨‍🚀Level 3 | 🌈 Color LED | +neopixel","visible": true }, - {"source_url": "Police_Siren.xml", "source_text": "👨‍🚀Level 3 | 🌈 Police Siren | +neopixel","visible": true }, - {"source_url": "bluetooth.xml","source_text": "👨‍🚀Level 3 | 📱 Bluetooth | +bluetooth","visible": true }, - {"source_url": "oled.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Display | +screen","visible": true}, - {"source_url": "dhttemp.xml","source_text": "👨‍🚀Level 3 | 🌡️ DHT Temperature Display | +dht sensor","visible": true}, - {"source_url": "oledshapes.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Shapes | +screen","visible": true}, - {"source_url": "oledframe.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Frame | +screen","visible": true}, - {"source_url": "oledanimation.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Animation | +screen","visible": true}, - {"source_url": "oledanimationwalk.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Animation Walk | +screen","visible": true}, - {"source_url": "Oledspectrumgraph.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Spectrum graph | +screen","visible": true}, - {"source_url": "oledicon.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Icon | +screen","visible": true}, - {"source_url": "oledmouth.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Mouth | +screen","visible": true}, - {"source_url": "oledmouths.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Mouths | +screen","visible": true}, - {"source_url": "oledlogo.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Logo | +screen","visible": true}, - {"source_url": "oledgyro.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Gyro | +screen","visible": true}, - {"source_url": "servocalibration.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Servo | +screen","visible": true}, - {"source_url": "oledlaser.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED Laser | +screen","visible": true}, - {"source_url": "Laser_Theremin.xml","source_text": "👨‍🚀Level 3 | ⚡ Laser_Theremin | +sensor","visible": true }, - {"source_url": "dfmini.xml","source_text": "👨‍🚀Level 3 | 🔊 MP3 basic | +dfmini","visible": true }, - {"source_url": "dfminitriggers.xml","source_text": "👨‍🚀Level 3 | 🔊 MP3 Triggers | +dfmini","visible": true }, - {"source_url": "TFTicon.xml","source_text": "👨‍🚀Level 3 | 📺 TFT Icon |+screen","visible": true }, - {"source_url": "TFTAnimation.xml","source_text": "👨‍🚀Level 3 | 📺 TFT Animation |+screen","visible": true }, - {"source_url": "IFTTT.xml","source_text": "👨‍🚀Level 3 | ☁️ IoT IFTTT | 🐱‍👤Ninja","visible": true }, - {"source_url": "MQTT.xml","source_text": "👨‍🚀Level 3 | ☁️ IoT MQTT | 🐱‍👤Ninja","visible": true }, - {"source_url": "NTP.xml","source_text": "👨‍🚀Level 3 | ☁️ IoT NTP | 🐱‍👤Ninja","visible": true }, - {"source_url": "Thingspeak.xml","source_text": "👨‍🚀Level 3 | ☁️ Thingspeak | 🐱‍👤Ninja","visible": true }, - {"source_url": "Telegram.xml","source_text": "👨‍🚀Level 3 | ☁️ Telegram | 🐱‍👤Ninja","visible": true }, - {"source_url": "Open_weather.xml","source_text": "👨‍🚀Level 3 | 🌨️ Open Weather | 🐱‍👤Ninja","visible": true }, - {"source_url": "MUvision.xml","source_text": "👨‍🚀Level 3 | 👁️ AI Camera | +MU vision camera","visible": true} + {"source_url": "servo.xml","source_text": "👶Level 1 | 🦿 Servo centering |","visible": true}, + {"source_url": "servosweep.xml","source_text": "👶Level 1 | 🦿 Servo sweep | ","visible": true}, + {"source_url": "Ottocalibration.xml","source_text": "👶Level 1 | 🤖 Otto basic calibration | ","visible": true }, + {"source_url": "Ottocalibrationapp.xml","source_text": "👶Level 1 | 🤖 Otto proper calibration with software | ","visible": true }, + {"source_url": "Ottobuzzer.xml","source_text": "👶Level 1 | 🔈 Otto sounds | ","visible": true}, + {"source_url": "melody.xml","source_text": "👶Level 1 | 🎼 Melody | ","visible": true}, + {"source_url": "RTTL.xml","source_text": "👶Level 1 | 🎼 Ring Tone sounds | ","visible": true}, + {"source_url": "Ottowalk.xml", "source_text": "👶Level 1 | 🤖 Otto walk | ", "visible": true }, + {"source_url": "Ottodance.xml","source_text": "👶Level 1 | 🤖 Otto dance | ","visible": true}, + {"source_url": "Ottodancerandom.xml","source_text": "👶Level 1 | 🤖 Otto random dancer | ","visible": true}, + {"source_url": "Ottoavoid.xml","source_text": "👶Level 1 | 🤖 Otto avoids obstacles | ","visible": true}, + {"source_url": "Ottoavoidpeople.xml","source_text": "👶Level 1 | 🤖 Otto avoids people | ","visible": true}, + {"source_url": "Ottofollow.xml","source_text": "👶Level 1 | 🌌 The force is with you | ","visible": true}, + {"source_url": "theremin.xml","source_text": "👶Level 1 | 🎹 Theremin | ","visible": true}, + {"source_url": "ninja.xml","source_text": "👶Level 1 | 🐱‍👤 Ninja basic |","visible": true}, + {"source_url": "ninjaapp.xml","source_text": "👶Level 1 | 🐱‍👤 Ninja App |","visible": true}, + {"source_url": "wheelsavoid.xml","source_text": "👶Level 1 | 🚗 Otto Wheels avoid |","visible": true}, + {"source_url": "serialdistance.xml","source_text": "👨‍💻Level 2 | 📏 Serial measure distance | ","visible": true }, + {"source_url": "touch.xml","source_text": "👨‍💻Level 2 | 👇 Touch sensor interaction |","visible": true}, + {"source_url": "noise.xml","source_text": "👨‍💻Level 2 | 👏 Sound sensor interaction |","visible": true}, + {"source_url": "serialnoise.xml","source_text": "👨‍💻Level 2 | 👏 Serial sound sensor readings |","visible": true }, + {"source_url": "touchsoundtest.xml","source_text": "👨‍💻Level 2 | 👇 Touch & 👏sound sensor test |","visible": true}, + {"source_url": "touchsoundultra.xml","source_text": "👨‍💻Level 2 | 🦇 Ultrasonic, 👇touch & 👏sound sensors |","visible": true}, + {"source_url": "matrixtest.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED mouth matrix test |","visible": true }, + {"source_url": "matrixmouths.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED mouth emotions | ","visible": true }, + {"source_url": "matrixmouthspeech.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED mouth speak |","visible": true }, + {"source_url": "matrixsing.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED mouth sing |","visible": true }, + {"source_url": "matrixcounter.xml","source_text": "👨‍💻Level 2 | 👄 8x8 LED mouth variable counter |","visible": true}, + {"source_url": "matrixhands.xml","source_text": "👨‍💻Level 2 | 🧼 8x8 LED mouth wash hands counter |","visible": true}, + {"source_url": "matrixeyestest.xml","source_text": "👨‍💻Level 2 | 👀 16x8 LED eyes matrix test |","visible": true }, + {"source_url": "matrixeyes.xml","source_text": "👨‍💻Level 2 | 👀 16x8 LED eyes matrix emotions | +eyes","visible": true}, + {"source_url": "ledfade.xml","source_text": "👨‍💻Level 2 | 💡 Single LED fade effect |","visible": true }, + {"source_url": "ledpot.xml","source_text": "👨‍💻Level 2 | 💡 Single LED + potentiometer |","visible": true }, + {"source_url": "ledfadepot.xml","source_text": "👨‍💻Level 2 | 💡 Single LED + potentiometer fade effect |","visible": true }, + {"source_url": "servoadvanced.xml","source_text": "👨‍💻Level 2 | 🦿 Servo advanced control | ","visible": true}, + {"source_url": "IFTTT.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + ☁️ IoT IFTTT | ","visible": true }, + {"source_url": "MQTT.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + ☁️ IoT MQTT |","visible": true }, + {"source_url": "NTP.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + ☁️ IoT NTP | ","visible": true }, + {"source_url": "Thingspeak.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + ☁️ Thingspeak |","visible": true }, + {"source_url": "Telegram.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + ☁️ Telegram |","visible": true }, + {"source_url": "Open_weather.xml","source_text": "👨‍🚀Level 3 | 🐱‍👤Ninja + 🌨️ Open Weather |","visible": true }, + {"source_url": "ottoky.xml","source_text": "👨‍🚀Level 3 | 👓 Ottoky happy |","visible": true }, + {"source_url": "ottokysense.xml","source_text": "👨‍🚀Level 3 | 🎛️ Ottoky sense |","visible": true }, + {"source_url": "ottokyiotclock.xml","source_text": "👨‍🚀Level 3 | 🌐 Ottoky clock |","visible": true }, + {"source_url": "ottokyavoid.xml","source_text": "👨‍🚀Level 3 | 🧠 Ottoky avoid |","visible": true }, + {"source_url": "ottokydht.xml","source_text": "👨‍🚀Level 3 | 🌡️ Ottoky temperature |","visible": true }, + {"source_url": "bluetooth.xml","source_text": "👨‍🚀Level 3 | 📱 Bluetooth blocks|","visible": true }, + {"source_url": "oled.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display |","visible": true}, + {"source_url": "oledshapes.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display shapes |","visible": true}, + {"source_url": "oledframe.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display frame | ","visible": true}, + {"source_url": "oledanimation.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display animation | ","visible": true}, + {"source_url": "oledanimationwalk.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display animation walk | ","visible": true}, + {"source_url": "Oledspectrumgraph.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display Spectrum graph | ","visible": true}, + {"source_url": "oledicon.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display icon | ","visible": true}, + {"source_url": "oledmouth.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display mouth | ","visible": true}, + {"source_url": "oledmouths.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display mouths | ","visible": true}, + {"source_url": "oledlogo.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display Logo | ","visible": true}, + {"source_url": "oledgyro.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display with Gyro sensor | ","visible": true}, + {"source_url": "servocalibration.xml","source_text": "👨‍🚀Level 3 | 🖥️ OLED display with Servo motor | ","visible": true}, + {"source_url": "dhttemp.xml","source_text": "👨‍🚀Level 3 | 🌡️ DHT Temperature in OLED display |","visible": true}, + {"source_url": "oledlaser.xml","source_text": "👨‍🚀Level 3 | ⚡ OLED display with Laser sensor | ","visible": true}, + {"source_url": "Laser_Theremin.xml","source_text": "👨‍🚀Level 3 | ⚡ Laser sensor into Theremin |","visible": true }, + {"source_url": "neopixel.xml", "source_text": "👨‍🚀Level 3 | 🌈 Color neopixel LED |","visible": true }, + {"source_url": "Police_Siren.xml", "source_text": "👨‍🚀Level 3 | 🌈 Color neopixel LED police siren |","visible": true }, + {"source_url": "dfmini.xml","source_text": "👨‍🚀Level 3 | 🔊 MP3 DF mini basics |","visible": true }, + {"source_url": "dfminitriggers.xml","source_text": "👨‍🚀Level 3 | 🔊 MP3 DF mini Triggers |","visible": true }, + {"source_url": "TFTicon.xml","source_text": "👨‍🚀Level 3 | 📺 TFT display Icon | ","visible": true }, + {"source_url": "TFTAnimation.xml","source_text": "👨‍🚀Level 3 | 📺 TFT display animation | ","visible": true }, + {"source_url": "irda.xml","source_text": "👨‍🚀Level 3 | 🎮 Remote infrared control |","visible": true}, + {"source_url": "MUvision.xml","source_text": "👨‍🚀Level 3 | 👁️ MU vision AI camera |","visible": true} ] \ No newline at end of file diff --git a/www/examples/ninja.xml b/www/examples/ninja.xml new file mode 100644 index 000000000..9fc8c225f --- /dev/null +++ b/www/examples/ninja.xml @@ -0,0 +1,121 @@ + + toolbox_arduino_all-esp8266 + + + + D8 + D7 + D3 + D4 + D0 + 3 + 1 + + + + + 0 + + + + + 0 + + + + + 90 + + + + + 180 + + + + + 0 + + + + + 90 + + + + + + + 20 + + + + + 20 + + + + + 20 + + + + + 20 + + + + + + + + + + + + + + + + + 3 + + + + + F + + + + + + + + + + + 3 + + + + + F + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/www/examples/ninjaapp.xml b/www/examples/ninjaapp.xml new file mode 100644 index 000000000..fa41c054d --- /dev/null +++ b/www/examples/ninjaapp.xml @@ -0,0 +1,92 @@ + + toolbox_arduino_all-esp8266 + + + + D8 + D7 + D3 + D4 + D0 + 3 + 1 + + + + + 0 + + + + + 0 + + + + + 90 + + + + + 180 + + + + + 0 + + + + + 90 + + + + + + + 20 + + + + + 20 + + + + + 20 + + + + + 20 + + + + + MyOttoNinja + 12345678 + + + + + + + + + + + This block should be use always alone for this particular example +after upload this code +1. Install and open the mobile App https://remotexy.com/en/download/ +2. Press + to add new device +3. Select Wifi point +4. "MyOttoNinja" should be visible in the options +5. Password 12345678 + + + + + \ No newline at end of file diff --git a/www/lang/Arduino_en.js b/www/lang/Arduino_en.js index 3b581f9a9..db50a4f62 100644 --- a/www/lang/Arduino_en.js +++ b/www/lang/Arduino_en.js @@ -78,7 +78,7 @@ Blockly.Msg.CAT_TCS34725 = "🌈 Color"; Blockly.Msg.CAT_Displays = "💻 Displays"; Blockly.Msg.CAT_OLED_U8G = "🖥️ OLED"; Blockly.Msg.CAT_TFT_ST7735 = "📺 TFT"; -Blockly.Msg.CAT_del = "💡 LED Single"; +Blockly.Msg.CAT_del = "🔆 GFX"; Blockly.Msg.CAT_LED = "💡 LED"; Blockly.Msg.CAT_LEDRGB = "🚥 LED RGB"; Blockly.Msg.CAT_NEOPIXEL = "🌈 NeoPixel"; diff --git a/www/toolbox/toolbox_arduino_all-esp8266.xml b/www/toolbox/toolbox_arduino_all-esp8266.xml index af05c0b89..d56769aab 100644 --- a/www/toolbox/toolbox_arduino_all-esp8266.xml +++ b/www/toolbox/toolbox_arduino_all-esp8266.xml @@ -1,8 +1,8 @@ - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_Displays,CAT_iot - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_SENSORS,CAT_servo,CAT_LED,CAT_com,CAT_Displays,CAT_AUDIO,CAT_MUVISION,CAT_iot - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_TAB,CAT_SENSORS,CAT_servo,CAT_LED,CAT_Displays,CAT_AUDIO,CAT_com,CAT_iot,CAT_MUVISION,CAT_STOCKAGE + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_ultrason,CAT_servo,CAT_ARDUINO_matrice16x8,CAT_del,CAT_BUZZER,CAT_iot + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_SENSORS,CAT_servo,CAT_LED,CAT_del,CAT_Displays,CAT_AUDIO,CAT_com,CAT_iot + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_TAB,CAT_SENSORS,CAT_actionneur,CAT_LED,CAT_del,CAT_Displays,CAT_AUDIO,CAT_com,CAT_iot,CAT_MUVISION,CAT_STOCKAGE @@ -234,50 +234,23 @@ - + - - 5 - + 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - @@ -295,6 +268,17 @@ + + + D3 + D4 + + + A0 + A0 + A6 + + A0 A0 @@ -689,17 +673,41 @@ - + + + + + + + + 0 + 0 + + + 0 + 0 + 8 + 5 + + + 0 + 0 + 7 + 3 + + + 4 + 4 + 3 + + + 0 + 0 + 8 + 8 + + - - - - - - - - - diff --git a/www/toolbox/toolbox_arduino_all.xml b/www/toolbox/toolbox_arduino_all.xml index 0314cbe43..192bd563e 100644 --- a/www/toolbox/toolbox_arduino_all.xml +++ b/www/toolbox/toolbox_arduino_all.xml @@ -1,8 +1,8 @@ - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_LOGIC,CAT_MATH,CAT_ultrason,CAT_servo,CAT_ARDUINO_matrice8x8,CAT_ARDUINO_matrice16x8,CAT_BUZZER - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_SENSORS,CAT_actionneur,CAT_LED,CAT_Displays,CAT_AUDIO,CAT_com - CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_TAB,CAT_SENSORS,CAT_actionneur,CAT_LED,CAT_Displays,CAT_AUDIO,CAT_com,CAT_KEYBOARD,CAT_MUVISION,CAT_STOCKAGE + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_LOGIC,CAT_MATH,CAT_ultrason,CAT_servo,CAT_ARDUINO_matrice8x8,CAT_ARDUINO_matrice16x8,CAT_del,CAT_BUZZER + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_SENSORS,CAT_servo,CAT_LED,CAT_del,CAT_Displays,CAT_AUDIO,CAT_com + CAT_ARDUINO,CAT_OTTO,CAT_ARDUINO_TIME,CAT_ARDUINO_IN,CAT_LOGIC,CAT_MATH,CAT_TEXT,CAT_FUNCTIONS,CAT_VARIABLES,CAT_TAB,CAT_SENSORS,CAT_actionneur,CAT_LED,CAT_del,CAT_Displays,CAT_AUDIO,CAT_com,CAT_KEYBOARD,CAT_MUVISION,CAT_STOCKAGE @@ -259,28 +259,18 @@ - - 5 - + 5 - - - - - - - - - - + + + - - + @@ -315,17 +305,15 @@ - - 8 - 9 - - - - A0 - - A6 - - + + 8 + 9 + + + A0 + A0 + A6 + A0 @@ -707,8 +695,6 @@ - - A2 @@ -719,6 +705,41 @@ + + + + + + + + + 0 + 0 + + + 0 + 0 + 8 + 5 + + + 0 + 0 + 7 + 3 + + + 4 + 4 + 3 + + + 0 + 0 + 8 + 8 + +