Howdy!
I have been wracking my brains on coming up with a two wire solution for my project.
The Project: gut out the proprietary electronics out of a Neopost Si-30 mail folder/inserter and use an Arduino MEGA2560 (Elegoo's ) as the beginning of it being an inserter. My first step was to build a hardware platform to test out the DC motors, stepper motors, flag sensors, linear hall effect sensors, and solenoids, using as few pins as possible.
I'm using a 20x4 Character I2C LCD with address 0x3F (the unusual address is due to difference between NXP and someone else's PCF8574.) I needed a 4x4 matrix keypad, also I2C like the folks at BrainyBits (A Keypad and LCD with only 2 Pins?! No problem with the I2C Protocol!
Oct 25, 2020) . And, I wanted an I2C 8-ch relay module using another of the PCF8574 modules.
By Tarantula3 in CircuitsArduino).
My Code is as follows:
/*
* collected by Ricky Robbins from examples from:
* // I2C Keypad library by Rob Tillaart https://github.com/RobTillaart/I2CKeyPad
* //LiquidCrystal_I2C maintained by Marco Schwartz https://github.com/johnrickman/LiquidCrystal_I2C
*
* 8 Channel Electromagnetic relay module board 5.0V 3.3V / 700mA
* I2C expander on PCF8574 or PCF8574A chip
* Logic level "0" ON relay, logic level "1" OFF relay
* works as is 7/22/23
*/
#include <Wire.h>
//#include <PCF8574.h>
#include <I2CKeyPad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,20,4);
const uint8_t KEYPAD_ADDRESS = 0x20;
I2CKeyPad keyPad(KEYPAD_ADDRESS);
char keymap[19] = "123A456B789C*0#DNF"; // N = NoKey, F = Fail
unsigned char addr = 0x22;
//PCF8574 i2c_rly(addr);
#define RLY_1_on 0b11111110
#define RLY_2_on 0b11111101
#define RLY_3_on 0b11111011
#define RLY_4_on 0b11110111
#define RLY_5_on 0b11101111
#define RLY_6_on 0b11011111
#define RLY_7_on 0b10111111
#define RLY_8_on 0b01111111
/*
#define RLY_1_off 0b00000001
#define RLY_2_off 0b00000010 these don't work as expected
#define RLY_3_off 0b00000100 7/28/23
#define RLY_4_off 0b00001000
#define RLY_5_off 0b00010000
#define RLY_6_off 0b00100000
#define RLY_7_off 0b01000000
#define RLY_8_off 0b10000000
*/
///////////////////////////////////////////////////////////////
void setup() {
lcd.init();
lcd.init();
lcd.backlight();
Wire.begin();
Wire.setClock(400000);
Wire.beginTransmission(addr);
Wire.write(0xFF); // Turns off all relays
Wire.endTransmission();
keyPad.loadKeyMap(keymap);
}
void i2c_relay(unsigned char addr, unsigned char value)
{
Wire.beginTransmission(addr);
Wire.write(value);
Wire.endTransmission();
}
//////////////////////////////////////////////////////////////////////
void loop()
{
if (keyPad.isPressed())
{
char ch = keyPad.getChar(); // note we want the translated char
int key = keyPad.getLastKey();
// Light up key pressed on LCD
switch (ch) {
case '1':
lcd.setCursor(0,0);
lcd.print(ch);
i2c_relay(addr, RLY_1_on);
break;
case '2':
lcd.setCursor(3,0);
lcd.print(ch);
i2c_relay(addr, RLY_2_on);
break;
case '3':
lcd.setCursor(6,0);
lcd.print(ch);
i2c_relay(addr, RLY_3_on);
break;
case '4':
lcd.setCursor(0,1);
lcd.print(ch);
i2c_relay(addr, RLY_4_on);
break;
case '5':
lcd.setCursor(3,1);
lcd.print(ch);
i2c_relay(addr, RLY_5_on);
break;
case '6':
lcd.setCursor(6,1);
lcd.print(ch);
i2c_relay(addr, RLY_6_on);
break;
case '7':
lcd.setCursor(0,2);
lcd.print(ch);
i2c_relay(addr, RLY_7_on);
break;
case '8':
lcd.setCursor(3,2);
lcd.print(ch);
i2c_relay(addr, RLY_8_on);
break;
/* case 'A':
lcd.setCursor(12,0);
lcd.print(ch);
break;
*/
case 'B':
lcd.setCursor(8,2);
lcd.print(ch);
i2c_relay(addr,0b11111111);
lcd.print(" All Off");
break;
/* case 'C':
lcd.setCursor(10,2);
lcd.print(ch);
break;
*/
case 'D':
lcd.setCursor(8,3);
lcd.print(ch);
lcd.print(" clear LCD");
delay(1000);
lcd.clear(); //lcd.clear();
break;
}
}
}
As I have cobbled and pasted to accomplish the following.
I am using an external 5VDC to the Rely module (Ox22). So what I can do is hit a number button 1-8, (4x4 membrane keypad connected to PCF8574 module at 0x20)and that number appears on a 20x04 LCD (0x3F) while that relay is turned on and stays on until the next number is pressed. It turns off the last relay engaged and turns on the one for the new keypress.
I know there is a different way of coding other than the Switch() Case() routine to be able to turn on a relay and have it stay energized while I turn on other relays attached to solenoids so I can run the DC motors all the time and yet turn on/off the relays for the solenoids accordingly.
I will also add another PCF8574 (8-chanel) expansion module to be able to connect it, using a different address, so I can view the activity of the flag sensors as a piece of paper travels throughout the machine with the motors and clutches engaged, until the contents (just 2 pieces) is placed into an envelope and run over the moistening flap, reversed direct to close the flap and send the closed envelope into a storage bin.
Back to my dilemma, I'm lost as far as how to have the 1-8 number on the LCD via the I2C 4x4 keypad while that relay stays energized and I can engage other relays at the same time.
Any and all help is appreciated. FYI the schematics are not included because it doesn't matter, what I have hooked up works fine.
I had forwarded the wrong sketch. this is the one that works on a 1-relay-at-a-time with each button press.