From 114365e2e8c502d3462243ee9f017d422c68f5f5 Mon Sep 17 00:00:00 2001 From: bquan0 Date: Fri, 20 Sep 2024 14:32:07 -0500 Subject: [PATCH 1/7] modify tutorial for PlatformIO --- .gitignore | 12 +++++------ .vscode/extensions.json | 10 +++++++++ .vscode/settings.json | 12 +++++++++++ include/mcp23017.h | 6 ++---- lib/README | 46 +++++++++++++++++++++++++++++++++++++++++ main.cpp | 10 --------- mbed-os.lib | 1 - mbed_app.json | 9 -------- platformio.ini | 14 +++++++++++++ src/main.cpp | 12 +++++++++++ src/mcp23017.cpp | 4 +--- test/README | 11 ++++++++++ 12 files changed, 114 insertions(+), 33 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 lib/README delete mode 100644 main.cpp delete mode 100644 mbed-os.lib delete mode 100644 mbed_app.json create mode 100644 platformio.ini create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/.gitignore b/.gitignore index 2bb52c9..63625a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -.build -.mbed -projectfiles -*.py* -mbed-os -BUILD +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +*.txt \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..356c0c8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "files.associations": { + "array": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "string_view": "cpp", + "initializer_list": "cpp", + "*.tcc": "cpp" + } +} \ No newline at end of file diff --git a/include/mcp23017.h b/include/mcp23017.h index b0306de..f3bb469 100644 --- a/include/mcp23017.h +++ b/include/mcp23017.h @@ -1,8 +1,7 @@ #ifndef __mcp__h__ #define __mcp__h__ -#include "mbed.h" -#include "stdint.h" +#include class Mcp23017 { @@ -10,10 +9,9 @@ class Mcp23017 { int set_dir(int pin, uint8_t dir); uint8_t get_dir(int pin); int addr; - I2C* i2cBus; public: - Mcp23017(int addr, I2C* i2cBus); + Mcp23017(int addr); int begin(uint8_t directions[8]); uint8_t get_state(int pin); int set_state(int pin, uint8_t val); diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/main.cpp b/main.cpp deleted file mode 100644 index a9373c7..0000000 --- a/main.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "mbed.h" -#include "mcp23017.h" - - -// TODO: Write tests here -int main(int argc, char **argv) -{ - printf("Hello world!\n"); - return 0; -} diff --git a/mbed-os.lib b/mbed-os.lib deleted file mode 100644 index 2b07903..0000000 --- a/mbed-os.lib +++ /dev/null @@ -1 +0,0 @@ -https://github.com/ARMmbed/mbed-os.git#2eb06e76208588afc6cb7580a8dd64c5429a10ce \ No newline at end of file diff --git a/mbed_app.json b/mbed_app.json deleted file mode 100644 index 589e589..0000000 --- a/mbed_app.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "requires": ["bare-metal"], - "target_overrides": { - "*": { - "target.printf_lib": "std", - "target.c_lib": "small" - } - } -} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..87af89e --- /dev/null +++ b/platformio.ini @@ -0,0 +1,14 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nucleo_f303re] +platform = ststm32 +board = nucleo_f303re +framework = arduino diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..daecad0 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,12 @@ +#include +#include "mcp23017.h" + +// TODO: declare mcp23017 object + +void setup() { + // TODO: initialize i2c and mcp23017 object +} + +void loop() { + // TODO: Write tests here +} \ No newline at end of file diff --git a/src/mcp23017.cpp b/src/mcp23017.cpp index 693ac79..9cb2515 100644 --- a/src/mcp23017.cpp +++ b/src/mcp23017.cpp @@ -1,12 +1,10 @@ #include "mcp23017.h" -#include - // TODO (optional): Define macros for useful register below: // TODO: Initialize i2cBus member -Mcp23017::Mcp23017(int addr, I2C* i2cBus) { +Mcp23017::Mcp23017(int addr) { } diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html From 91e016ae90c50d9d0023c5efc2a28e13d570acd3 Mon Sep 17 00:00:00 2001 From: bquan0 Date: Fri, 20 Sep 2024 15:09:56 -0500 Subject: [PATCH 2/7] update README.md to match arduino version --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 51aa6c7..d55cef0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Device Driver Tutorial -*Authors: Ben Everson, Wilson Guo* +*Authors: Ben Everson, Wilson Guo, Bowen Quan* A hands-on introduction to Badgerloop embedded device driver architecture, development, and testing. @@ -48,11 +48,11 @@ The bits in the GPIO port register correspond to the level of each GPIO pin. As I know that was a lot of information, but now you should understand the mechanisms we are going to use to interact with the pins on our MCP23017. This section of the tutorial will involve implementing functions to configure, monitor, and control the pins on an MCP23017. - Let's start by looking at the I2C serial communication class. Take a look at the definition of the I2C class in the [MbedOS API](https://os.mbed.com/docs/mbed-os/v6.15/apis/i2c.html). Since the Mcp23017 class will contain an instance of the I2C class, it's important to unerstand the protected methods we will have at our disposal. These methods are already implemented, but we will be using them to actually send messages on the I2C bus. The two important methods we will use in this tutorial are the `write (int address, const char *data, int length, bool repeated=false)` method and the `read (int address, char *data, int length, bool repeated=false)`. + Let's start by looking at the I2C serial communication class. We will use [Arduino's Wire library](https://www.arduino.cc/reference/en/language/functions/communication/wire/) for this. The important methods we will use are: [write()](https://www.arduino.cc/reference/en/language/functions/communication/wire/write), [read()](https://www.arduino.cc/reference/en/language/functions/communication/wire/read), and other related methods like `beginTransmission()`, `endTransmission()`, `requestFrom()`. Make sure to look at the examples in `write()` and `read()` links to see how they are used and how the related methods are used. **Note**: The data in an I2C message is always one or more bytes long. This means that we can't just tell the device to write or read a single bit of a register. We will always be dealing with all 8 bits, AKA a byte, at once. - Now that we know what functions we will use to read and write the MCP23017 registers, we can start implementing the functions defined in [include/mcp23017.h](include/mcp23017.h). The stubs are layed out for you in [src/mcp23017.cpp](src/mcp23017.cpp). If you feel confident in implementing these functions, give it a try! Feel free to skip to [Testing](#testing) section once you are done. If you still feel like you need some help, I will go over each of these methods one by one. + Now that we know what functions we will use to read and write the MCP23017 registers, we can start implementing the functions defined in [include/mcp23017.h](include/mcp23017.h). The stubs are laid out for you in [src/mcp23017.cpp](src/mcp23017.cpp). If you feel confident in implementing these functions, give it a try! Feel free to skip to [Testing](#testing) section once you are done. If you still feel like you need some help, I will go over each of these methods one by one. **Note:** You will see a data type, `uint8_t`, that might not be familiar to you. This data type represents an unsigned 8 bit integer (a byte). It will be used whenever we are dealing with register addresses and values. @@ -60,7 +60,7 @@ I know that was a lot of information, but now you should understand the mechanis This function simply needs to record the identifying information that we pass in (the device address) and store the I2C instance that we use to access the bus. You will see how we use these members later when we access the device. **`get_dir`**
- This function should return the value of a specific pin's direction. To do this, we will need to do a few things. First, we need to first specify to the MCP what register we want to read from by writing the proper register offset to it. Second, we will need to read from the iodir register we just specified. Third, since we have to read the value of the entire register (remember we can't just read one bit), we have to do some bitwise arithmetic to figure out what part of the byte we read corresponds to the pin we are looking for. Finally, we can return that value. + This function should return the value of a specific pin's direction. To do this, we will need to do a few things. First, we need to first specify to the MCP what register we want to read from by writing the proper register offset to it. Second, we will need to read **a byte** from the iodir register we just specified. Third, we have to do some bitwise arithmetic to figure out what part of **the byte** we read corresponds to the pin we are looking for. Finally, we can return that value. **Hint:** You might find use for the and (&) and shift right(>>) operators to filter out the pin you are looking for. @@ -78,10 +78,10 @@ I know that was a lot of information, but now you should understand the mechanis Similar to how `get_dir` was nearly identical to `get_state`, `set_state` is going to be very similar to `set_dir` . There shouldn't be too many changes here. **`begin`**
- This function is responsible for confirming I2C communication between the computer and the device, as well as setting the direction of each pin on the device. While all of the I2C initialization is handled by the `I2C` class, it is often a good idea to perform a verifiable I2C transaction to make sure everything is working correctly. Most I2C devices contain a register that holds what is called a Device ID number. Look in the datasheet and see if you can find this register and the corresponding ID number for the MCP23017. If we can read and verify this number in the `begin` function, we can have confidence that our I2C communication is working properly. You will also be setting the direction of each pin using the function(s) you implemented above. Note that this function takes in an array of 8 integers called `directions`. These will correspond to the direction of each pin in the device's bank. + This function is responsible for confirming I2C communication between the computer and the device, as well as setting the direction of each pin on the device. It is a good idea to perform a verifiable I2C transaction to make sure everything is working correctly. Most I2C devices contain a register that holds what is called a Device ID number, but the MCP23017 doesn't. So, we will use the IODIRA register as our "Device ID" register instead. If we can read and verify the default value of the IODIRA register in the `begin` function, we can have confidence that our I2C communication is working properly. You will also be setting the direction of each pin using the function(s) you implemented above. Note that this function takes in an array of 8 integers called `directions`. These will correspond to the direction of each pin in the device's bank. ## Testing - So you wrote your driver, but now you have to test it. The first step you should take is to make sure the functions you implemented all compile. You can do this by clicking the hammer; make sure that you have chosen `driver-dev-tutorial` as the current project and `Nucleo-F767ZI` as the target. You will have to take some time working through any syntax errors you have. It might get a little frustrating, especially if you aren't very familiar with C++. Feel free to reach out in the firmware channel if you get stuck on anything specific. + To test, first make sure the functions you implemented all compile by clicking the check mark at the bottom bar of VS Code. The target has already been set as the Nucleo F303RE. Work through any syntax errors you may have. It might get a little frustrating, especially if you aren't very familiar with C++. Feel free to reach out in the firmware channel if you get stuck on anything specific. Now that you have a device class that compiles, you can write code to test your functions. This code should be in the `main` function in [main.cpp](main.cpp). Assume the MCP23017 is connected like so: ![circuit.png](images/circuit.png) @@ -89,4 +89,4 @@ Now that you have a device class that compiles, you can write code to test your As you can see, two LEDs are tied to pins 0 and 4. There is also a switch connected to pin 7. Can you initialize an Mcp23017 object and use the functions you implemented to turn the LEDs on and read the position of the switch? -We will try to schedule times to get you running your code on this hardware setup. :) +We will try to schedule times to get you running your code on this hardware setup. :) \ No newline at end of file From c6639e1a666ef66960c92826ca55d9e387409852 Mon Sep 17 00:00:00 2001 From: Tristin Yun Date: Fri, 18 Oct 2024 13:12:28 -0500 Subject: [PATCH 3/7] Tristin Yun Driver Dev Tutorial 2024 --- src/main.cpp | 10 ++++++ src/mcp23017.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 88 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index daecad0..5ba2e70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,11 +2,21 @@ #include "mcp23017.h" // TODO: declare mcp23017 object +Mcp23017 mcp23017(0x20); + void setup() { // TODO: initialize i2c and mcp23017 object + Wire.begin(); + //Start serial + Serial.begin(9600); + Serial.println("Starting process..."); } void loop() { // TODO: Write tests here + uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 0}; + mcp23017.begin(directions); + mcp23017.get_state(0); + mcp23017.set_state(0, 1); } \ No newline at end of file diff --git a/src/mcp23017.cpp b/src/mcp23017.cpp index 9cb2515..ee50050 100644 --- a/src/mcp23017.cpp +++ b/src/mcp23017.cpp @@ -1,39 +1,108 @@ #include "mcp23017.h" // TODO (optional): Define macros for useful register below: - +#define ioDirAddr 0x00 +#define GPIOAddr 0x09 // TODO: Initialize i2cBus member -Mcp23017::Mcp23017(int addr) { - +Mcp23017::Mcp23017(int addr) : addr(addr) { //member initializxation + Wire.begin(addr); // Start wire library and join i2c bus } uint8_t Mcp23017::get_dir(int pin) { - return 0; + // request 1 byte from the register at 0x00 (iodir) + // and store in the variable byteRead + Wire.requestFrom(ioDirAddr, 1); + uint8_t byteRead; + while (Wire.available()){ + byteRead = Wire.read(); + } + //moves desired bit to LSB and compares to 1 + uint8_t pinDir = (byteRead >> pin) & 1; + return pinDir; } // TODO: Read from state register uint8_t Mcp23017::get_state(int pin) { - return 0; + // Same functionality as above method + Wire.requestFrom(GPIOAddr, 1); + uint8_t byteRead; + while (Wire.available()){ + byteRead = Wire.read(); + } + uint8_t pinDir = (byteRead >> pin) & 1; + return pinDir; } // TODO: Write to directions register int Mcp23017::set_dir(int pin, uint8_t dir) { - return 0; + Wire.requestFrom(ioDirAddr, 1); + uint8_t byte; + while (Wire.available()){ + byte = Wire.read(); + } + if(dir == 1){ //If we want the pin to be on, we use OR logic + byte |= (dir << pin); // shift the mask by the pin amount + } + else if(dir == 0){ //Use AND NOT logic to get the pin to be off + byte &= ~(dir << pin); + } + Wire.beginTransmission(ioDirAddr); //transmit the byte + Wire.write(byte); + Wire.endTransmission(); + + return get_dir(pin); //checks if what we did worked } // TODO: Write to state register int Mcp23017::set_state(int pin, uint8_t val) { - return 0; + Wire.requestFrom(GPIOAddr, 1); + uint8_t byte; + while (Wire.available()){ + byte = Wire.read(); + } + if(val == 1){ + byte |= (val << pin); + } + else if(val == 0){ + byte &= ~(val << pin); + } + Wire.beginTransmission(GPIOAddr); + Wire.write(byte); + Wire.endTransmission(); + + return get_state(pin); } // Verifies that the device is accessible over I2C and sets pin directions int Mcp23017::begin(uint8_t directions[8]) { int rc; + Wire.beginTransmission(ioDirAddr); + //this method with nothing overloaded will return 0 if successful + //and a different integer if it fails + rc = Wire.endTransmission(); + + if(rc == 0){ + Serial.println("IODIR Address verified at 0x"); + Serial.println(ioDirAddr, HEX); + } + else { + Serial.println("No device found at address 0x"); + Serial.println(ioDirAddr, HEX); + } - // TODO: Add device ID check + //set the direction of each of the pins to the desired value + for(int i = 0; i < 8; i++){ + set_dir(i, directions[i]); + } - return 0; + //returns 1 byte from IODIR to see if the addresses were successfully changed + Wire.requestFrom(ioDirAddr, 1); + uint8_t byte; + while (Wire.available()){ + byte = Wire.read(); + } + return byte; } From c3b85a68431b693409d919cd26406c747347cb75 Mon Sep 17 00:00:00 2001 From: Tristin Yun <53619342+Nexnar@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:57:21 -0500 Subject: [PATCH 4/7] V2 main.cpp --- src/main.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 5ba2e70..295b763 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include +al#include #include "mcp23017.h" // TODO: declare mcp23017 object @@ -8,6 +8,8 @@ Mcp23017 mcp23017(0x20); void setup() { // TODO: initialize i2c and mcp23017 object Wire.begin(); + uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 0}; + mcp23017.begin(directions); //Start serial Serial.begin(9600); Serial.println("Starting process..."); @@ -15,8 +17,11 @@ void setup() { void loop() { // TODO: Write tests here - uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 0}; - mcp23017.begin(directions); - mcp23017.get_state(0); + + //Toggles the state of the first pin and prints it + Serial.println(mcp23017.get_state(0)); mcp23017.set_state(0, 1); -} \ No newline at end of file + Serial.println(mcp23017.get_state(0)); + mcp23017.set_state(0, 0); + delay(1000); //delay so it doesn't loop so quickly +} From cc9cf4c06cb0b6c52e8b3d66e485971f2e91fe21 Mon Sep 17 00:00:00 2001 From: Tristin Yun <53619342+Nexnar@users.noreply.github.com> Date: Sun, 20 Oct 2024 00:07:42 -0500 Subject: [PATCH 5/7] V2 mcp23017.cpp --- src/mcp23017.cpp | 74 ++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/src/mcp23017.cpp b/src/mcp23017.cpp index ee50050..c40e119 100644 --- a/src/mcp23017.cpp +++ b/src/mcp23017.cpp @@ -1,18 +1,22 @@ #include "mcp23017.h" // TODO (optional): Define macros for useful register below: -#define ioDirAddr 0x00 -#define GPIOAddr 0x09 +#define IO_DIR_ADDR 0x00 +#define GPIO_ADDR 0x09 // TODO: Initialize i2cBus member -Mcp23017::Mcp23017(int addr) : addr(addr) { //member initializxation - Wire.begin(addr); // Start wire library and join i2c bus -} +Mcp23017::Mcp23017(int addr) : addr(addr) {} //member initialization uint8_t Mcp23017::get_dir(int pin) { + // first establish a connection with the i2bus + Wire.beginTransmission(Mcp23017::addr); + //Specify the register + Wire.write(IO_DIR_ADDR); + Wire.endTransmission(); + // request 1 byte from the register at 0x00 (iodir) // and store in the variable byteRead - Wire.requestFrom(ioDirAddr, 1); + Wire.requestFrom(IO_DIR_ADDR, 1); uint8_t byteRead; while (Wire.available()){ byteRead = Wire.read(); @@ -26,7 +30,12 @@ uint8_t Mcp23017::get_dir(int pin) { // TODO: Read from state register uint8_t Mcp23017::get_state(int pin) { // Same functionality as above method - Wire.requestFrom(GPIOAddr, 1); + Wire.beginTransmission(Mcp23017::addr); + //Specify the register + Wire.write(GPIO_ADDR); + Wire.endTransmission(); + + Wire.requestFrom(GPIO_ADDR, 1); uint8_t byteRead; while (Wire.available()){ byteRead = Wire.read(); @@ -37,7 +46,11 @@ uint8_t Mcp23017::get_state(int pin) { // TODO: Write to directions register int Mcp23017::set_dir(int pin, uint8_t dir) { - Wire.requestFrom(ioDirAddr, 1); + Wire.beginTransmission(Mcp23017::addr); + Wire.write(IO_DIR_ADDR); + Wire.endTransmission(); + + Wire.requestFrom(IO_DIR_ADDR, 1); uint8_t byte; while (Wire.available()){ byte = Wire.read(); @@ -46,9 +59,10 @@ int Mcp23017::set_dir(int pin, uint8_t dir) { byte |= (dir << pin); // shift the mask by the pin amount } else if(dir == 0){ //Use AND NOT logic to get the pin to be off - byte &= ~(dir << pin); + byte &= ~(1 << pin); } - Wire.beginTransmission(ioDirAddr); //transmit the byte + Wire.beginTransmission(Mcp23017::addr); + Wire.write(IO_DIR_ADDR); Wire.write(byte); Wire.endTransmission(); @@ -57,7 +71,11 @@ int Mcp23017::set_dir(int pin, uint8_t dir) { // TODO: Write to state register int Mcp23017::set_state(int pin, uint8_t val) { - Wire.requestFrom(GPIOAddr, 1); + Wire.beginTransmission(Mcp23017::addr); + Wire.write(GPIO_ADDR); + Wire.endTransmission(); + + Wire.requestFrom(GPIO_ADDR, 1); uint8_t byte; while (Wire.available()){ byte = Wire.read(); @@ -66,9 +84,11 @@ int Mcp23017::set_state(int pin, uint8_t val) { byte |= (val << pin); } else if(val == 0){ - byte &= ~(val << pin); + byte &= ~(1 << pin); } - Wire.beginTransmission(GPIOAddr); + + Wire.beginTransmission(Mcp23017::addr); + Wire.write(GPIO_ADDR); Wire.write(byte); Wire.endTransmission(); @@ -79,18 +99,18 @@ int Mcp23017::set_state(int pin, uint8_t val) { // Verifies that the device is accessible over I2C and sets pin directions int Mcp23017::begin(uint8_t directions[8]) { int rc; - Wire.beginTransmission(ioDirAddr); - //this method with nothing overloaded will return 0 if successful - //and a different integer if it fails - rc = Wire.endTransmission(); + + Wire.beginTransmission(Mcp23017::addr); + Wire.write(IO_DIR_ADDR); + Wire.endTransmission(); - if(rc == 0){ - Serial.println("IODIR Address verified at 0x"); - Serial.println(ioDirAddr, HEX); + Wire.requestFrom(IO_DIR_ADDR, 1); + uint8_t rc; + while (Wire.available()){ + rc = Wire.read(); } - else { - Serial.println("No device found at address 0x"); - Serial.println(ioDirAddr, HEX); + if(rc != 0xFF){ //according to manual, all of the bits should be on at first + return 0; //failed } //set the direction of each of the pins to the desired value @@ -98,11 +118,5 @@ int Mcp23017::begin(uint8_t directions[8]) { set_dir(i, directions[i]); } - //returns 1 byte from IODIR to see if the addresses were successfully changed - Wire.requestFrom(ioDirAddr, 1); - uint8_t byte; - while (Wire.available()){ - byte = Wire.read(); - } - return byte; + return 1; //succeeded } From 8db1e0af56b438e88910123e90cafee047d41024 Mon Sep 17 00:00:00 2001 From: Tristin Yun <53619342+Nexnar@users.noreply.github.com> Date: Mon, 21 Oct 2024 17:18:17 -0500 Subject: [PATCH 6/7] Update main.cpp --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 295b763..5b96e2d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,7 @@ Mcp23017 mcp23017(0x20); void setup() { // TODO: initialize i2c and mcp23017 object Wire.begin(); - uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 0}; + uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 1, 0}; mcp23017.begin(directions); //Start serial Serial.begin(9600); @@ -21,6 +21,7 @@ void loop() { //Toggles the state of the first pin and prints it Serial.println(mcp23017.get_state(0)); mcp23017.set_state(0, 1); + delay(1000); //delay so we can see the pin state change Serial.println(mcp23017.get_state(0)); mcp23017.set_state(0, 0); delay(1000); //delay so it doesn't loop so quickly From 1682050a1fcb5e1b07106baa9c41a89efd582bda Mon Sep 17 00:00:00 2001 From: Tristin Yun <53619342+Nexnar@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:53:49 -0500 Subject: [PATCH 7/7] Update main.cpp --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 5b96e2d..ca63a1e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,7 @@ Mcp23017 mcp23017(0x20); void setup() { // TODO: initialize i2c and mcp23017 object Wire.begin(); - uint8_t directions[8] = {1, 1, 1, 1, 1, 1, 1, 0}; + uint8_t directions[8] = {0, 1, 1, 1, 1, 1, 1, 0}; mcp23017.begin(directions); //Start serial Serial.begin(9600);