Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Troubleshooting
  3. ERROR - 'decode_type_t' does not name a type

ERROR - 'decode_type_t' does not name a type

Scheduled Pinned Locked Moved Troubleshooting
2 Posts 2 Posters 1.9k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Newzwaver
    wrote on last edited by mfalkvidd
    #1

    Hi
    Attached below I am getting an error trying to upgrade to 2.1.1 lib, it must be where the files are saved (I think???). ANy helpw would be great.

    Thanks

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Changed for MySensors usage by Bart Eversdijk
     * Version 1.1 - Added option to record manual presets up to 240
     * Version 2.0 - Migrated to MySensrors version 2.0
     * 
     * DESCRIPTION
     *
     * IRrecord: record and play back IR signals as a minimal 
     * An IR detector/demodulator must be connected to the input RECV_PIN.
     * An IR LED must be connected to the output PWM pin 3.
     *
     *
     * The logic is:
     * If a V_IR_RECORD is received the node enters in record mode and once a valid IR message has been received 
     * it is stored in EEPROM. The first byte of the V_IR_RECORD message will be used as preset ID 
     * 
     * If a V_IR_SEND the IR message beloning to the preset number of the first message byte is broadcasted
     *
     *
     * Version 0.11 September, 2009
     * Copyright 2009 Ken Shirriff
     * http://arcfn.com
     */
    
    // Enable debug prints
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    #define MY_NODE_ID      5
    
    #include <SPI.h>
    #include <MySensors.h>
    
    #include <IRremote.h>  // https://github.com/z3t0/Arduino-IRremote/releases   
    // OR install IRRemote via "Sketch" -> "Include Library" -> "Manage Labraries..."
    // Search for IRRemote b shirif and press the install button
    
    // Arduino pin to connect the IR receiver to
    int RECV_PIN     = 8;
    
    #define CHILD_ID  2  
    
    #define MY_RAWBUF  50
    const char * TYPE2STRING[] = {
    		"UNKONWN",
    		"RC5",
    		"RC6",
    		"NEC",
    		"Sony",
    		"Panasonic",
    		"JVC",
    		"SAMSUNG",
    		"Whynter",
    		"AIWA RC T501",
    		"LG",
    		"Sanyo",
    		"Mitsubishi",
    		"Dish",
    		"Sharp",
    		"Denon"
    };
    #define Type2String(x)   TYPE2STRING[x < 0 ? 0 : x]
    #define AddrTxt          F(" addres: 0x")
    #define ValueTxt         F(" value: 0x")
    #define NATxt            F(" - not implemented/found")
    
    // Raw or unknown codes requires an Arduino with a larger memory like a MEGA and some changes to store in EEPROM (now max 255 bytes)
    // #define IR_SUPPORT_UNKNOWN_CODES
    typedef union
    {
      struct
      {
        decode_type_t type;            // The type of code
        unsigned long value;           // The data bits if type is not raw
        int           len;             // The length of the code in bits
        unsigned int  address;         // Used by Panasonic & Sharp [16-bits]
      } code;
    #ifdef IR_SUPPORT_UNKNOWN_CODES      
      struct
      {
        decode_type_t type;             // The type of code
        unsigned int  codes[MY_RAWBUF];
        byte          count;           // The number of interval samples
      } raw;
    #endif
    } IRCode;
    
    #define           MAX_STORED_IR_CODES     10
    IRCode            StoredIRCodes[MAX_STORED_IR_CODES];
    
    IRrecv            irrecv(RECV_PIN);
    IRsend            irsend;
    decode_results    ircode;
    
    #define           NO_PROG_MODE 0xFF
    byte              progModeId       = NO_PROG_MODE;
    
    // Manual Preset IR values -- these are working demo values
    // VERA call: luup.call_action("urn:schemas-arduino-cc:serviceId:ArduinoIr1", "SendIrCode", {Index=15}, <device number>)
    // One can add up to 240 preset codes (if your memory lasts) to see to correct data connect the Arduino with this plug in and
    // look at the serial monitor while pressing the desired RC button
    IRCode PresetIRCodes[] = {
        { { RC5, 0x01,       12, 0 }},  // 11 - RC5 key "1" 
        { { RC5, 0x02,       12, 0 }},  // 12 - RC5 key "2"
        { { RC5, 0x03,       12, 0 }},  // 13 - RC5 key "3"
        { { NEC, 0xFF30CF,   32, 0 }},  // 14 - NEC key "1"
        { { NEC, 0xFF18E7,   32, 0 }},  // 15 - NEC key "2"
        { { NEC, 0xFF7A85,   32, 0 }},  // 16 - NEC key "3"
        { { NEC, 0xFF10EF,   32, 0 }},  // 17 - NEC key "4"
        { { NEC, 0xFF38C7,   32, 0 }},  // 18 - NEC key "5"
        { { RC6, 0x800F2401, 36, 0 }},  // 19 - RC6 key "1" MicroSoft Mulitmedia RC
        { { RC6, 0x800F2402, 36, 0 }}   // 20 - RC6 key "2" MicroSoft Mulitmedia RC
    };
    #define MAX_PRESET_IR_CODES  (sizeof(PresetIRCodes)/sizeof(IRCode))
    #define MAX_IR_CODES (MAX_STORED_IR_CODES + MAX_PRESET_IR_CODES)
    
    MyMessage msgIrReceive(CHILD_ID, V_IR_RECEIVE);
    MyMessage msgIrRecord(CHILD_ID, V_IR_RECORD); 
    
    void setup()  
    {  
      // Tell MYS Controller that we're NOT recording
      send(msgIrRecord.set(0));
      
      Serial.println(F("Recall EEPROM settings"));
      recallEeprom(sizeof(StoredIRCodes), (byte *)&StoredIRCodes);
    
      // Start the ir receiver
      irrecv.enableIRIn(); 
      
      Serial.println(F("Init done..."));
    }
    
    void presentation () 
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("IR Rec/Playback", "2.0");
    
      // Register a sensors to gw. Use binary light for test purposes.
      present(CHILD_ID, S_IR);
    }
    
    void loop() 
    {
      if (irrecv.decode(&ircode)) {
          dump(&ircode);
          if (progModeId != NO_PROG_MODE) {
             // If we are in PROG mode (Recording) store the new IR code and end PROG mode
             if (storeRCCode(progModeId)) {
                Serial.println(F("Stored "));
              
                // If sucessfull RC decode and storage --> also update the EEPROM
                storeEeprom(sizeof(StoredIRCodes), (byte *)&StoredIRCodes);
                progModeId = NO_PROG_MODE;
               
                // Tell MYS Controller that we're done recording
                send(msgIrRecord.set(0));
             }
          } else {
             // If we are in Playback mode just tell the MYS Controller we did receive an IR code
             if (ircode.decode_type != UNKNOWN) {
                 if (ircode.value != REPEAT) {
                   // Look if we found a stored preset 0 => not found
                   byte num = lookUpPresetCode(&ircode);
                   if (num) {
                       // Send IR decode result to the MYS Controller
                       Serial.print(F("Found code for preset #"));
                       Serial.println(num);
                       send(msgIrReceive.set(num));
                   }
                 }
             }
        }
        // Wait a while before receive next IR-code (also block MySensors receiver so it will not interfere with a new message)
        delay(500);
        
        // Start receiving again
        irrecv.resume();
      }
    }
    
    void receive(const MyMessage &message) {
        //Serial.print(F("New message: "));
        //Serial.println(message.type);
       
       if (message.type == V_IR_RECORD) { // IR_RECORD V_VAR1
          // Get IR record requets for index : paramvalue
          progModeId = message.getByte() % MAX_STORED_IR_CODES;
          
          // Tell MYS Controller that we're now in recording mode
          send(msgIrRecord.set(1));
          
          Serial.print(F("Record new IR for: "));
          Serial.println(progModeId);
       }
      
       if (message.type == V_IR_SEND) {
          // Send an IR code from offset: paramvalue - no check for legal value
          Serial.print(F("Send IR preset: "));
          byte code = message.getByte() % MAX_IR_CODES;
          if (code == 0) {
            code = MAX_IR_CODES;
          }
          Serial.print(code);
          sendRCCode(code);
       }
    
       // Start receiving ir again...
       irrecv.enableIRIn(); 
    }
    
    
    byte lookUpPresetCode (decode_results *ircode)
    {
        // Get rit of the RC5/6 toggle bit when looking up
        if (ircode->decode_type == RC5)  {
            ircode->value = ircode->value & 0x7FF;
        }
        if (ircode->decode_type == RC6)  {
            ircode->value = ircode->value & 0xFFFF7FFF;
        }
        for (byte index = 0; index < MAX_STORED_IR_CODES; index++)
        {
          if ( StoredIRCodes[index].code.type  == ircode->decode_type &&
               StoredIRCodes[index].code.value == ircode->value       &&
               StoredIRCodes[index].code.len   == ircode->bits)      {
              // The preset number starts with 1 so the last is stored as 0 -> fix this when looking up the correct index
              return (index == 0) ? MAX_STORED_IR_CODES : index;
          }  
        }
        
        for (byte index = 0; index < MAX_PRESET_IR_CODES; index++)
        {
          if ( PresetIRCodes[index].code.type  == ircode->decode_type &&
               PresetIRCodes[index].code.value == ircode->value       &&
               PresetIRCodes[index].code.len   == ircode->bits)      {
              // The preset number starts with 1 so the last is stored as 0 -> fix this when looking up the correct index
              return ((index == 0) ? MAX_PRESET_IR_CODES : index) + MAX_STORED_IR_CODES;
          }  
        }
        // not found so return 0
        return 0;
    }
        
    // Stores the code for later playback
    bool storeRCCode(byte index) {
    
      if (ircode.decode_type == UNKNOWN) {
    #ifdef IR_SUPPORT_UNKNOWN_CODES  
          Serial.println(F("Received unknown code, saving as raw"));
          // To store raw codes:
          // Drop first value (gap)
          // As of v1.3 of IRLib global values are already in microseconds rather than ticks
          // They have also been adjusted for overreporting/underreporting of marks and spaces
          byte rawCount = min(ircode.rawlen - 1, MY_RAWBUF);
          for (int i = 1; i <= rawCount; i++) {
            StoredIRCodes[index].raw.codes[i - 1] = ircode.rawbuf[i]; // Drop the first value
          };
          return true;
    #else 
          return false;
        }
    #endif
    
       if (ircode.value == REPEAT) {
           // Don't record a NEC repeat value as that's useless.
           Serial.println(F("repeat; ignoring."));
           return false;
       }
       // Get rit of the toggle bit when storing RC5/6 
       if (ircode.decode_type == RC5)  {
            ircode.value = ircode.value & 0x07FF;
       }
       if (ircode.decode_type == RC6)  {
            ircode.value = ircode.value & 0xFFFF7FFF;
       }
    
       StoredIRCodes[index].code.type      = ircode.decode_type;
       StoredIRCodes[index].code.value     = ircode.value;
       StoredIRCodes[index].code.address   = ircode.address;      // Used by Panasonic & Sharp [16-bits]
       StoredIRCodes[index].code.len       = ircode.bits;
       Serial.print(F(" value: 0x"));
       Serial.println(ircode.value, HEX);
       return true;
    }
    
    void sendRCCode(byte index) {
       IRCode *pIr = ((index <= MAX_STORED_IR_CODES) ? &StoredIRCodes[index % MAX_STORED_IR_CODES] : &PresetIRCodes[index - MAX_STORED_IR_CODES - 1]);
       
    #ifdef IR_SUPPORT_UNKNOWN_CODES  
       if(pIr->code.type == UNKNOWN) {
          // Assume 38 KHz
          irsend.sendRaw(pIr->raw.codes, pIr->raw.count, 38);
          Serial.println(F("Sent raw"));
          return;
       }
    #endif
    
       Serial.print(F(" - sent "));
       Serial.print(Type2String(pIr->code.type));
       if (pIr->code.type == RC5) {
           // For RC5 and RC6 there is a toggle bit for each succesor IR code sent alway toggle this bit, needs to repeat the command 3 times with 100 mS pause
           pIr->code.value ^= 0x0800;
           for (byte i=0; i < 3; i++) {
             if (i > 0) { delay(100); } 
             irsend.sendRC5(pIr->code.value, pIr->code.len);
           }
        } 
        else if (pIr->code.type == RC6) {
           // For RC5 and RC6 there is a toggle bit for each succesor IR code sent alway toggle this bit, needs to repeat the command 3 times with 100 mS pause
           if (pIr->code.len == 20) {
                  pIr->code.value ^= 0x10000;
           }
           for (byte i=0; i < 3; i++) {
             if (i > 0) { delay(100); } 
             irsend.sendRC6(pIr->code.value, pIr->code.len);
           }
       }
       else if (pIr->code.type == NEC) {
           irsend.sendNEC(pIr->code.value, pIr->code.len);
        } 
        else if (pIr->code.type == SONY) {
           irsend.sendSony(pIr->code.value, pIr->code.len);
        } 
        else if (pIr->code.type == PANASONIC) {
           irsend.sendPanasonic(pIr->code.address, pIr->code.value);
           Serial.print(AddrTxt);
           Serial.println(pIr->code.address, HEX);
        }
        else if (pIr->code.type == JVC) {
           irsend.sendJVC(pIr->code.value, pIr->code.len, false);
        }
        else if (pIr->code.type == SAMSUNG) {
           irsend.sendSAMSUNG(pIr->code.value, pIr->code.len);
        }
        else if (pIr->code.type == WHYNTER) {
           irsend.sendWhynter(pIr->code.value, pIr->code.len);
        }
        else if (pIr->code.type == AIWA_RC_T501) {
           irsend.sendAiwaRCT501(pIr->code.value);
        }
        else if (pIr->code.type == LG || pIr->code.type == SANYO || pIr->code.type == MITSUBISHI) {
           Serial.println(NATxt);
           return;
        }
        else if (pIr->code.type == DISH) {
          // need to repeat the command 4 times with 100 mS pause
          for (byte i=0; i < 4; i++) {
             if (i > 0) { delay(100); } 
               irsend.sendDISH(pIr->code.value, pIr->code.len);
          }
        }
        else if (pIr->code.type == SHARP) {
           irsend.sendSharp(pIr->code.address, pIr->code.value);
           Serial.print(AddrTxt);
           Serial.println(pIr->code.address, HEX);
        }
        else if (pIr->code.type == DENON) {
           irsend.sendDenon(pIr->code.value, pIr->code.len);
        }
        else {
          // No valid IR type, found it does not make sense to broadcast
          Serial.println(NATxt);
          return; 
        }
        Serial.print(" ");
        Serial.println(pIr->code.value, HEX);
    }    
    
    // Dumps out the decode_results structure.
    void dump(decode_results *results) {
        int count = results->rawlen;
        
        Serial.print(F("Received : "));
        Serial.print(results->decode_type, DEC);
        Serial.print(F(" "));
        Serial.print(Type2String(results->decode_type));
      
        if (results->decode_type == PANASONIC) {	
          Serial.print(AddrTxt);
          Serial.print(results->address,HEX);
          Serial.print(ValueTxt);
        }
        Serial.print(F(" "));
        Serial.print(results->value, HEX);
        Serial.print(F(" ("));
        Serial.print(results->bits, DEC);
        Serial.println(F(" bits)"));
      
        if (results->decode_type == UNKNOWN) {
          Serial.print(F("Raw ("));
          Serial.print(count, DEC);
          Serial.print(F("): "));
      
          for (int i = 0; i < count; i++) {
            if ((i % 2) == 1) {
              Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
            } 
            else {
              Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
            }
            Serial.print(" ");
          }
          Serial.println("");
        }
    }
    
    // Store IR record struct in EEPROM   
    void storeEeprom(byte len, byte *buf)
    {
        saveState(0, len);
        for (byte i = 1; i < min(len, 100); i++, buf++)
        {
           saveState(i, *buf);
        }
    }
    
    void recallEeprom(byte len, byte *buf)
    {
        if (loadState(0) != len)
        {
           Serial.print(F("Corrupt EEPROM preset values and Clear EEPROM"));
           for (byte i = 1; i < min(len, 100); i++, buf++)
           {
               *buf = 0;
               storeEeprom(len, buf);
           }
           return;
        }
        for (byte i = 1; i < min(len, 100); i++, buf++)
        {
           *buf = loadState(i);
        }
    }
    
    ERROR
    Arduino: 1.6.5 (Windows 8.1), Board: "Arduino Nano, ATmega328"
    
    Using library SPI in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI 
    
    Using library MySensors in folder: C:\Users\Audrey\Documents\Arduino\libraries\MySensors 
    
    Using library Robot IR Remote in folder: C:\Program Files (x86)\Arduino\libraries\RobotIRremote 
    
    
    
    C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI -IC:\Users\Audrey\Documents\Arduino\libraries\MySensors -IC:\Program Files (x86)\Arduino\libraries\RobotIRremote\src C:\Users\Audrey\AppData\Local\Temp\build1415505741175231405.tmp\IrSensor.cpp -o C:\Users\Audrey\AppData\Local\Temp\build1415505741175231405.tmp\IrSensor.cpp.o 
    
    IrSensor.ino:95:5: error: 'decode_type_t' does not name a type
    IrSensor.ino:114:1: error: 'IRsend' does not name a type
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
    IrSensor.ino: In function 'byte lookUpPresetCode(decode_results*)':
    IrSensor.ino:246:38: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:256:38: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino: In function 'bool storeRCCode(byte)':
    IrSensor.ino:300:30: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:302:49: error: 'class decode_results' has no member named 'address'
    IrSensor.ino: In function 'void sendRCCode(byte)':
    IrSensor.ino:322:39: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:84:38: note: in definition of macro 'Type2String'
    IrSensor.ino:322:39: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:84:50: note: in definition of macro 'Type2String'
    IrSensor.ino:323:18: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:328:10: error: 'irsend' was not declared in this scope
    IrSensor.ino:331:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:338:10: error: 'irsend' was not declared in this scope
    IrSensor.ino:341:23: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:342:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:344:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:345:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:347:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:348:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:352:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:353:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:355:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:355:32: error: 'SAMSUNG' was not declared in this scope
    IrSensor.ino:356:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:358:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:358:32: error: 'WHYNTER' was not declared in this scope
    IrSensor.ino:359:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:361:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:361:32: error: 'AIWA_RC_T501' was not declared in this scope
    IrSensor.ino:362:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:364:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:364:32: error: 'LG' was not declared in this scope
    IrSensor.ino:364:48: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:364:75: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:368:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:372:12: error: 'irsend' was not declared in this scope
    IrSensor.ino:375:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:376:8: error: 'irsend' was not declared in this scope
    IrSensor.ino:380:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
    IrSensor.ino:380:32: error: 'DENON' was not declared in this scope
    IrSensor.ino:381:8: error: 'irsend' was not declared in this scope
    IrSensor.ino: In function 'void dump(decode_results*)':
    IrSensor.ino:403:29: error: 'class decode_results' has no member named 'address'
    'decode_type_t' does not name a type
    
    mfalkviddM 1 Reply Last reply
    0
    • N Newzwaver

      Hi
      Attached below I am getting an error trying to upgrade to 2.1.1 lib, it must be where the files are saved (I think???). ANy helpw would be great.

      Thanks

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Changed for MySensors usage by Bart Eversdijk
       * Version 1.1 - Added option to record manual presets up to 240
       * Version 2.0 - Migrated to MySensrors version 2.0
       * 
       * DESCRIPTION
       *
       * IRrecord: record and play back IR signals as a minimal 
       * An IR detector/demodulator must be connected to the input RECV_PIN.
       * An IR LED must be connected to the output PWM pin 3.
       *
       *
       * The logic is:
       * If a V_IR_RECORD is received the node enters in record mode and once a valid IR message has been received 
       * it is stored in EEPROM. The first byte of the V_IR_RECORD message will be used as preset ID 
       * 
       * If a V_IR_SEND the IR message beloning to the preset number of the first message byte is broadcasted
       *
       *
       * Version 0.11 September, 2009
       * Copyright 2009 Ken Shirriff
       * http://arcfn.com
       */
      
      // Enable debug prints
      #define MY_DEBUG
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      #define MY_NODE_ID      5
      
      #include <SPI.h>
      #include <MySensors.h>
      
      #include <IRremote.h>  // https://github.com/z3t0/Arduino-IRremote/releases   
      // OR install IRRemote via "Sketch" -> "Include Library" -> "Manage Labraries..."
      // Search for IRRemote b shirif and press the install button
      
      // Arduino pin to connect the IR receiver to
      int RECV_PIN     = 8;
      
      #define CHILD_ID  2  
      
      #define MY_RAWBUF  50
      const char * TYPE2STRING[] = {
      		"UNKONWN",
      		"RC5",
      		"RC6",
      		"NEC",
      		"Sony",
      		"Panasonic",
      		"JVC",
      		"SAMSUNG",
      		"Whynter",
      		"AIWA RC T501",
      		"LG",
      		"Sanyo",
      		"Mitsubishi",
      		"Dish",
      		"Sharp",
      		"Denon"
      };
      #define Type2String(x)   TYPE2STRING[x < 0 ? 0 : x]
      #define AddrTxt          F(" addres: 0x")
      #define ValueTxt         F(" value: 0x")
      #define NATxt            F(" - not implemented/found")
      
      // Raw or unknown codes requires an Arduino with a larger memory like a MEGA and some changes to store in EEPROM (now max 255 bytes)
      // #define IR_SUPPORT_UNKNOWN_CODES
      typedef union
      {
        struct
        {
          decode_type_t type;            // The type of code
          unsigned long value;           // The data bits if type is not raw
          int           len;             // The length of the code in bits
          unsigned int  address;         // Used by Panasonic & Sharp [16-bits]
        } code;
      #ifdef IR_SUPPORT_UNKNOWN_CODES      
        struct
        {
          decode_type_t type;             // The type of code
          unsigned int  codes[MY_RAWBUF];
          byte          count;           // The number of interval samples
        } raw;
      #endif
      } IRCode;
      
      #define           MAX_STORED_IR_CODES     10
      IRCode            StoredIRCodes[MAX_STORED_IR_CODES];
      
      IRrecv            irrecv(RECV_PIN);
      IRsend            irsend;
      decode_results    ircode;
      
      #define           NO_PROG_MODE 0xFF
      byte              progModeId       = NO_PROG_MODE;
      
      // Manual Preset IR values -- these are working demo values
      // VERA call: luup.call_action("urn:schemas-arduino-cc:serviceId:ArduinoIr1", "SendIrCode", {Index=15}, <device number>)
      // One can add up to 240 preset codes (if your memory lasts) to see to correct data connect the Arduino with this plug in and
      // look at the serial monitor while pressing the desired RC button
      IRCode PresetIRCodes[] = {
          { { RC5, 0x01,       12, 0 }},  // 11 - RC5 key "1" 
          { { RC5, 0x02,       12, 0 }},  // 12 - RC5 key "2"
          { { RC5, 0x03,       12, 0 }},  // 13 - RC5 key "3"
          { { NEC, 0xFF30CF,   32, 0 }},  // 14 - NEC key "1"
          { { NEC, 0xFF18E7,   32, 0 }},  // 15 - NEC key "2"
          { { NEC, 0xFF7A85,   32, 0 }},  // 16 - NEC key "3"
          { { NEC, 0xFF10EF,   32, 0 }},  // 17 - NEC key "4"
          { { NEC, 0xFF38C7,   32, 0 }},  // 18 - NEC key "5"
          { { RC6, 0x800F2401, 36, 0 }},  // 19 - RC6 key "1" MicroSoft Mulitmedia RC
          { { RC6, 0x800F2402, 36, 0 }}   // 20 - RC6 key "2" MicroSoft Mulitmedia RC
      };
      #define MAX_PRESET_IR_CODES  (sizeof(PresetIRCodes)/sizeof(IRCode))
      #define MAX_IR_CODES (MAX_STORED_IR_CODES + MAX_PRESET_IR_CODES)
      
      MyMessage msgIrReceive(CHILD_ID, V_IR_RECEIVE);
      MyMessage msgIrRecord(CHILD_ID, V_IR_RECORD); 
      
      void setup()  
      {  
        // Tell MYS Controller that we're NOT recording
        send(msgIrRecord.set(0));
        
        Serial.println(F("Recall EEPROM settings"));
        recallEeprom(sizeof(StoredIRCodes), (byte *)&StoredIRCodes);
      
        // Start the ir receiver
        irrecv.enableIRIn(); 
        
        Serial.println(F("Init done..."));
      }
      
      void presentation () 
      {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("IR Rec/Playback", "2.0");
      
        // Register a sensors to gw. Use binary light for test purposes.
        present(CHILD_ID, S_IR);
      }
      
      void loop() 
      {
        if (irrecv.decode(&ircode)) {
            dump(&ircode);
            if (progModeId != NO_PROG_MODE) {
               // If we are in PROG mode (Recording) store the new IR code and end PROG mode
               if (storeRCCode(progModeId)) {
                  Serial.println(F("Stored "));
                
                  // If sucessfull RC decode and storage --> also update the EEPROM
                  storeEeprom(sizeof(StoredIRCodes), (byte *)&StoredIRCodes);
                  progModeId = NO_PROG_MODE;
                 
                  // Tell MYS Controller that we're done recording
                  send(msgIrRecord.set(0));
               }
            } else {
               // If we are in Playback mode just tell the MYS Controller we did receive an IR code
               if (ircode.decode_type != UNKNOWN) {
                   if (ircode.value != REPEAT) {
                     // Look if we found a stored preset 0 => not found
                     byte num = lookUpPresetCode(&ircode);
                     if (num) {
                         // Send IR decode result to the MYS Controller
                         Serial.print(F("Found code for preset #"));
                         Serial.println(num);
                         send(msgIrReceive.set(num));
                     }
                   }
               }
          }
          // Wait a while before receive next IR-code (also block MySensors receiver so it will not interfere with a new message)
          delay(500);
          
          // Start receiving again
          irrecv.resume();
        }
      }
      
      void receive(const MyMessage &message) {
          //Serial.print(F("New message: "));
          //Serial.println(message.type);
         
         if (message.type == V_IR_RECORD) { // IR_RECORD V_VAR1
            // Get IR record requets for index : paramvalue
            progModeId = message.getByte() % MAX_STORED_IR_CODES;
            
            // Tell MYS Controller that we're now in recording mode
            send(msgIrRecord.set(1));
            
            Serial.print(F("Record new IR for: "));
            Serial.println(progModeId);
         }
        
         if (message.type == V_IR_SEND) {
            // Send an IR code from offset: paramvalue - no check for legal value
            Serial.print(F("Send IR preset: "));
            byte code = message.getByte() % MAX_IR_CODES;
            if (code == 0) {
              code = MAX_IR_CODES;
            }
            Serial.print(code);
            sendRCCode(code);
         }
      
         // Start receiving ir again...
         irrecv.enableIRIn(); 
      }
      
      
      byte lookUpPresetCode (decode_results *ircode)
      {
          // Get rit of the RC5/6 toggle bit when looking up
          if (ircode->decode_type == RC5)  {
              ircode->value = ircode->value & 0x7FF;
          }
          if (ircode->decode_type == RC6)  {
              ircode->value = ircode->value & 0xFFFF7FFF;
          }
          for (byte index = 0; index < MAX_STORED_IR_CODES; index++)
          {
            if ( StoredIRCodes[index].code.type  == ircode->decode_type &&
                 StoredIRCodes[index].code.value == ircode->value       &&
                 StoredIRCodes[index].code.len   == ircode->bits)      {
                // The preset number starts with 1 so the last is stored as 0 -> fix this when looking up the correct index
                return (index == 0) ? MAX_STORED_IR_CODES : index;
            }  
          }
          
          for (byte index = 0; index < MAX_PRESET_IR_CODES; index++)
          {
            if ( PresetIRCodes[index].code.type  == ircode->decode_type &&
                 PresetIRCodes[index].code.value == ircode->value       &&
                 PresetIRCodes[index].code.len   == ircode->bits)      {
                // The preset number starts with 1 so the last is stored as 0 -> fix this when looking up the correct index
                return ((index == 0) ? MAX_PRESET_IR_CODES : index) + MAX_STORED_IR_CODES;
            }  
          }
          // not found so return 0
          return 0;
      }
          
      // Stores the code for later playback
      bool storeRCCode(byte index) {
      
        if (ircode.decode_type == UNKNOWN) {
      #ifdef IR_SUPPORT_UNKNOWN_CODES  
            Serial.println(F("Received unknown code, saving as raw"));
            // To store raw codes:
            // Drop first value (gap)
            // As of v1.3 of IRLib global values are already in microseconds rather than ticks
            // They have also been adjusted for overreporting/underreporting of marks and spaces
            byte rawCount = min(ircode.rawlen - 1, MY_RAWBUF);
            for (int i = 1; i <= rawCount; i++) {
              StoredIRCodes[index].raw.codes[i - 1] = ircode.rawbuf[i]; // Drop the first value
            };
            return true;
      #else 
            return false;
          }
      #endif
      
         if (ircode.value == REPEAT) {
             // Don't record a NEC repeat value as that's useless.
             Serial.println(F("repeat; ignoring."));
             return false;
         }
         // Get rit of the toggle bit when storing RC5/6 
         if (ircode.decode_type == RC5)  {
              ircode.value = ircode.value & 0x07FF;
         }
         if (ircode.decode_type == RC6)  {
              ircode.value = ircode.value & 0xFFFF7FFF;
         }
      
         StoredIRCodes[index].code.type      = ircode.decode_type;
         StoredIRCodes[index].code.value     = ircode.value;
         StoredIRCodes[index].code.address   = ircode.address;      // Used by Panasonic & Sharp [16-bits]
         StoredIRCodes[index].code.len       = ircode.bits;
         Serial.print(F(" value: 0x"));
         Serial.println(ircode.value, HEX);
         return true;
      }
      
      void sendRCCode(byte index) {
         IRCode *pIr = ((index <= MAX_STORED_IR_CODES) ? &StoredIRCodes[index % MAX_STORED_IR_CODES] : &PresetIRCodes[index - MAX_STORED_IR_CODES - 1]);
         
      #ifdef IR_SUPPORT_UNKNOWN_CODES  
         if(pIr->code.type == UNKNOWN) {
            // Assume 38 KHz
            irsend.sendRaw(pIr->raw.codes, pIr->raw.count, 38);
            Serial.println(F("Sent raw"));
            return;
         }
      #endif
      
         Serial.print(F(" - sent "));
         Serial.print(Type2String(pIr->code.type));
         if (pIr->code.type == RC5) {
             // For RC5 and RC6 there is a toggle bit for each succesor IR code sent alway toggle this bit, needs to repeat the command 3 times with 100 mS pause
             pIr->code.value ^= 0x0800;
             for (byte i=0; i < 3; i++) {
               if (i > 0) { delay(100); } 
               irsend.sendRC5(pIr->code.value, pIr->code.len);
             }
          } 
          else if (pIr->code.type == RC6) {
             // For RC5 and RC6 there is a toggle bit for each succesor IR code sent alway toggle this bit, needs to repeat the command 3 times with 100 mS pause
             if (pIr->code.len == 20) {
                    pIr->code.value ^= 0x10000;
             }
             for (byte i=0; i < 3; i++) {
               if (i > 0) { delay(100); } 
               irsend.sendRC6(pIr->code.value, pIr->code.len);
             }
         }
         else if (pIr->code.type == NEC) {
             irsend.sendNEC(pIr->code.value, pIr->code.len);
          } 
          else if (pIr->code.type == SONY) {
             irsend.sendSony(pIr->code.value, pIr->code.len);
          } 
          else if (pIr->code.type == PANASONIC) {
             irsend.sendPanasonic(pIr->code.address, pIr->code.value);
             Serial.print(AddrTxt);
             Serial.println(pIr->code.address, HEX);
          }
          else if (pIr->code.type == JVC) {
             irsend.sendJVC(pIr->code.value, pIr->code.len, false);
          }
          else if (pIr->code.type == SAMSUNG) {
             irsend.sendSAMSUNG(pIr->code.value, pIr->code.len);
          }
          else if (pIr->code.type == WHYNTER) {
             irsend.sendWhynter(pIr->code.value, pIr->code.len);
          }
          else if (pIr->code.type == AIWA_RC_T501) {
             irsend.sendAiwaRCT501(pIr->code.value);
          }
          else if (pIr->code.type == LG || pIr->code.type == SANYO || pIr->code.type == MITSUBISHI) {
             Serial.println(NATxt);
             return;
          }
          else if (pIr->code.type == DISH) {
            // need to repeat the command 4 times with 100 mS pause
            for (byte i=0; i < 4; i++) {
               if (i > 0) { delay(100); } 
                 irsend.sendDISH(pIr->code.value, pIr->code.len);
            }
          }
          else if (pIr->code.type == SHARP) {
             irsend.sendSharp(pIr->code.address, pIr->code.value);
             Serial.print(AddrTxt);
             Serial.println(pIr->code.address, HEX);
          }
          else if (pIr->code.type == DENON) {
             irsend.sendDenon(pIr->code.value, pIr->code.len);
          }
          else {
            // No valid IR type, found it does not make sense to broadcast
            Serial.println(NATxt);
            return; 
          }
          Serial.print(" ");
          Serial.println(pIr->code.value, HEX);
      }    
      
      // Dumps out the decode_results structure.
      void dump(decode_results *results) {
          int count = results->rawlen;
          
          Serial.print(F("Received : "));
          Serial.print(results->decode_type, DEC);
          Serial.print(F(" "));
          Serial.print(Type2String(results->decode_type));
        
          if (results->decode_type == PANASONIC) {	
            Serial.print(AddrTxt);
            Serial.print(results->address,HEX);
            Serial.print(ValueTxt);
          }
          Serial.print(F(" "));
          Serial.print(results->value, HEX);
          Serial.print(F(" ("));
          Serial.print(results->bits, DEC);
          Serial.println(F(" bits)"));
        
          if (results->decode_type == UNKNOWN) {
            Serial.print(F("Raw ("));
            Serial.print(count, DEC);
            Serial.print(F("): "));
        
            for (int i = 0; i < count; i++) {
              if ((i % 2) == 1) {
                Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
              } 
              else {
                Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
              }
              Serial.print(" ");
            }
            Serial.println("");
          }
      }
      
      // Store IR record struct in EEPROM   
      void storeEeprom(byte len, byte *buf)
      {
          saveState(0, len);
          for (byte i = 1; i < min(len, 100); i++, buf++)
          {
             saveState(i, *buf);
          }
      }
      
      void recallEeprom(byte len, byte *buf)
      {
          if (loadState(0) != len)
          {
             Serial.print(F("Corrupt EEPROM preset values and Clear EEPROM"));
             for (byte i = 1; i < min(len, 100); i++, buf++)
             {
                 *buf = 0;
                 storeEeprom(len, buf);
             }
             return;
          }
          for (byte i = 1; i < min(len, 100); i++, buf++)
          {
             *buf = loadState(i);
          }
      }
      
      ERROR
      Arduino: 1.6.5 (Windows 8.1), Board: "Arduino Nano, ATmega328"
      
      Using library SPI in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI 
      
      Using library MySensors in folder: C:\Users\Audrey\Documents\Arduino\libraries\MySensors 
      
      Using library Robot IR Remote in folder: C:\Program Files (x86)\Arduino\libraries\RobotIRremote 
      
      
      
      C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs -IC:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI -IC:\Users\Audrey\Documents\Arduino\libraries\MySensors -IC:\Program Files (x86)\Arduino\libraries\RobotIRremote\src C:\Users\Audrey\AppData\Local\Temp\build1415505741175231405.tmp\IrSensor.cpp -o C:\Users\Audrey\AppData\Local\Temp\build1415505741175231405.tmp\IrSensor.cpp.o 
      
      IrSensor.ino:95:5: error: 'decode_type_t' does not name a type
      IrSensor.ino:114:1: error: 'IRsend' does not name a type
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino:135:1: error: too many initializers for 'IRCode::<anonymous struct>'
      IrSensor.ino: In function 'byte lookUpPresetCode(decode_results*)':
      IrSensor.ino:246:38: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:256:38: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino: In function 'bool storeRCCode(byte)':
      IrSensor.ino:300:30: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:302:49: error: 'class decode_results' has no member named 'address'
      IrSensor.ino: In function 'void sendRCCode(byte)':
      IrSensor.ino:322:39: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:84:38: note: in definition of macro 'Type2String'
      IrSensor.ino:322:39: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:84:50: note: in definition of macro 'Type2String'
      IrSensor.ino:323:18: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:328:10: error: 'irsend' was not declared in this scope
      IrSensor.ino:331:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:338:10: error: 'irsend' was not declared in this scope
      IrSensor.ino:341:23: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:342:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:344:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:345:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:347:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:348:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:352:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:353:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:355:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:355:32: error: 'SAMSUNG' was not declared in this scope
      IrSensor.ino:356:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:358:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:358:32: error: 'WHYNTER' was not declared in this scope
      IrSensor.ino:359:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:361:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:361:32: error: 'AIWA_RC_T501' was not declared in this scope
      IrSensor.ino:362:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:364:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:364:32: error: 'LG' was not declared in this scope
      IrSensor.ino:364:48: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:364:75: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:368:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:372:12: error: 'irsend' was not declared in this scope
      IrSensor.ino:375:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:376:8: error: 'irsend' was not declared in this scope
      IrSensor.ino:380:24: error: 'struct IRCode::<anonymous>' has no member named 'type'
      IrSensor.ino:380:32: error: 'DENON' was not declared in this scope
      IrSensor.ino:381:8: error: 'irsend' was not declared in this scope
      IrSensor.ino: In function 'void dump(decode_results*)':
      IrSensor.ino:403:29: error: 'class decode_results' has no member named 'address'
      'decode_type_t' does not name a type
      
      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #2

      @Newzwaver sorry for the late reply.

      Try removing the MySensors folder (with the Arduino IDE closed) and then re-install MySensors using the Library Manager inside the Arduino IDE.

      1 Reply Last reply
      0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      10

      Online

      11.9k

      Users

      11.2k

      Topics

      113.4k

      Posts


      Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • MySensors
      • OpenHardware.io
      • Categories
      • Recent
      • Tags
      • Popular