I have a Grove 6-position DIP switch. It uses I2C to read the switch. I want to use it on a MKR NB 1500. I installed the library according to the instructions here: Grove - 6-Position DIP Switch | Seeed Studio Wiki
I get compile errors where it can't find twoWire or something similar. I am not home right now so I don't know the exact error. There is an include for Wire.h, but I could not find that library in the Library manager so that may be a problem.
I have the Grove LCD 16x2 display which also uses I2C and that works OK, so I know I2C works with the MKR NB 1500.
The example program comes with the library, and it has events for when the switches are moved which is more than I need. All I want to do is read the value of the DIP switch, so if you have any ideas about that please let me know.
Has anyone successfully compiled and used the example program?
/*
Name: Grove_Multi_Switch.h
Grove 5-Way Tactile & Grove 6-Position DIP Switch library.
Author: turmary <turmary@126.com>
Copyright (c) 2018 Seeed Corporation.
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __GROVE_MULTI_SWITCH__
#define __GROVE_MULTI_SWITCH__
#include <stdint.h>
#include <Wire.h>
class GroveMultiSwitch {
public:
enum button_event_t {
BTN_EV_NO_EVENT = 0,
BTN_EV_HAS_EVENT = 0x80000000UL,
#define RAW_DIGITAL_BTN_PRESSED 0
#define RAW_DIP_SWITCH_ON 0
BTN_EV_RAW_STATUS = 1UL << 0,
BTN_EV_SINGLE_CLICK = 1UL << 1,
BTN_EV_DOUBLE_CLICK = 1UL << 2,
BTN_EV_LONG_PRESS = 1UL << 3,
BTN_EV_LEVEL_CHANGED = 1UL << 4,
};
struct ButtonEvent_t {
uint32_t event; // BTN_EV_NO_EVENT/BTN_EV_HAS_EVENT
#define BUTTON_MAX 6
uint8_t button[BUTTON_MAX]; // one button each element
};
/**
Create GroveMultiSwitch object.
@param addr - The i2c address of device.
@return - none
*/
#define _MULTI_SWITCH_DEF_I2C_ADDR 0x03 // The device i2c address in default
GroveMultiSwitch(uint8_t addr = _MULTI_SWITCH_DEF_I2C_ADDR) {
m_devAddr = addr;
m_i2c = &Wire;
version = 0;
}
/**
Initialize the switch interface
@return bool - true for success or false for fail
*/
bool begin(void) {
m_i2c->begin();
probeDevID();
// versions needed
getDevVer();
m_btnCnt = getSwitchCount();
return (m_btnCnt > 0);
}
/**
@param none
@return - Vendor ID(high 16 bits) & Product ID(low 16 bits)
0 if device unexist.
*/
uint32_t getDevID(void) {
return m_devID;
}
#define VID_VAL(x) ((x) >> 16)
#define PID_VAL(x) ((x) & 0xFFFFUL)
#define VID_MULTI_SWITCH 0x2886 // Vender ID of the device
#define PID_5_WAY_TACTILE_SWITCH 0x0002 // Grove 5-Way Tactile
#define PID_6_POS_DIP_SWITCH 0x0003 // Grove 6-Position DIP Switch
/**
Get device model and version
@return - NULL if device unexist.
*/
const char* getDevVer(void);
/**
Change i2c address of device.
@param addr - The new i2c address of device.
@return - none
*/
void setDevAddr(uint8_t addr);
/**
Get button/Switch count
*/
int getSwitchCount(void);
/**
Disable or enable event detecting mode.
Tactile switch events: single/double click, long press
DIP switch events : level changed
Raw switch status could be checked by getEvent()
no matter what mode has been setup.
Tactile switch status: press/non-press
DIP switch status : switch on/off
@param enable - true for enable, else for disable.
@return bool - true for success or false for fail
*/
bool setEventMode(bool enable);
/**
Get button/switch event,
refer to setEventMode() to get all available events.
@return ButtonEvent_t* -
NULL if error, such as device unexist.
.event = BTN_EV_NO_EVENT if no event
.event = BTN_EV_HAS_EVENT if event occured,
and .button to check event of each button/switch.
*/
ButtonEvent_t* getEvent(void);
private:
int readDev(uint8_t* data, int len);
int writeDev(const uint8_t* data, int len);
int readReg(uint8_t reg, uint8_t* data, int len);
/**
probe device & it's VID & PID
*/
uint32_t probeDevID(void);
#define _MULTI_SWITCH_VERSIONS_SZ 10
char versions[_MULTI_SWITCH_VERSIONS_SZ];
int version;
TwoWire* m_i2c;
uint8_t m_devAddr;
uint32_t m_btnCnt;
uint32_t m_devID;
public:
// debug purpose
int errno;
};
#endif //__GROVE_MULTI_SWITCH__
Here are the errors:
<code>
In file included from C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.cpp:30:0:
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.h:159:5: error: 'TwoWire' does not name a type; did you mean 'TwoWire_h'?
TwoWire* m_i2c;
^~~~~~~
TwoWire_h
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.h: In constructor 'GroveMultiSwitch::GroveMultiSwitch(uint8_t)':
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.h:66:9: error: 'm_i2c' was not declared in this scope
m_i2c = &Wire;
^~~~~
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.h: In member function 'bool GroveMultiSwitch::begin()':
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.h:76:9: error: 'm_i2c' was not declared in this scope
m_i2c->begin();
^~~~~
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.cpp: In member function 'int GroveMultiSwitch::readDev(uint8_t*, int)':
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.cpp:50:5: error: 'm_i2c' was not declared in this scope
m_i2c->requestFrom((int)m_devAddr, len);
^~~~~
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.cpp: In member function 'int GroveMultiSwitch::writeDev(const uint8_t*, int)':
C:\Users\Tom\Documents\Arduino\libraries\Grove_Multiple_Switch_library\src\Grove_Multi_Switch.cpp:68:5: error: 'm_i2c' was not declared in this scope
m_i2c->beginTransmission(m_devAddr);
^~~~~
exit status 1
Compilation error: exit status 1
</code>
Check your version of Wire.h, that it declares a class TwoWire.
On my system this file resides in
F:\Arduino\hardware\arduino\avr\libraries\Wire\src
maybe different for your system.
Later on you may have trouble with the I2C address 3. Valid I2C addresses reside above 8.
It was a brand new install of the IDE last week so I expect I have the latest versions. I could not find Wire.h using the library manager. Since I am using a SamD board, maybe it didn't think Wire.h should be loaded? My Grove 16x2 LCD uses I2C and it works fine.
I'll look for the Wire.h file. Doesn't the compiler give an error if one of the include files is missing? I got no error like that.
Most probably the standard file Wire.h is not missing on your system, but it misses the expected TwoWire class declaration. Find out how that class is named on your installation.
Let me be more clear. I sent an email to their tech support two days ago and searched the forum and found one topic where someone had the same issue 4 months ago.
I just now sent tech support another email and replied to the topic that I was having the same problem. I never would have thought reading a DIP switch would be so difficult. This is the only I2C dip switch I could find to buy. The I2C fits my project well as I have few pins left and don't want to dedicate them to a dip switch.
I haven't found the Wire.h file yet either. I was hoping that someone would download the library and try to compile the example to verify the error. You don't need the switch to get the error, just hit the check mark.
On my portable IDE v1.18.19 installation, the wire library is here:
D:\arduino-1.8.19\portable\packages\arduino\hardware\samd\1.8.13\libraries\Wire
I believe your problem is that the definition of all the Arduino core classes for this board are encapsulated in a namespace called "arduino". For example, in wire.h:
namespace arduino {
class TwoWire : public HardwareI2C
{
public:
The declaration of the Wire object occurs outside of this namespace (wire.h):
extern arduino::TwoWire Wire;
That would be fine, but your Grove library tries to use a pointer to an object of the TwoWire class. Try modifying Grove_Multi_Switch.h:
There was one occurrence of TwoWire* in the .h file.
I changed it to arduino::TwoWire* m_i2c;
Now I get these errors: 'TwoWire' does not name a type; did you mean 'TwoWire_h'? and 'm_i2c' was not declared in this scope.
I used the Windows file explorer to search for Wire.h and it didn't find any file of that name.