Now that we have considered what ball valves to connect to what outputs and sensor inputs we can start programming the Arduino TapHat.
Overview of all steps:
1. Preparing Raspberry Pi
2. Testing the TapHat / Pi connection – Arduino side
3. Testing the TapHat / Pi connection – Pi side
4. Connecting your Hardware
5. Configuring your TapHat and valves
6. Tap Control from the Internet
7. Finishing our Python Tap Control program
First we need to create a basic protocol for controlling the valves. We at least have three parameters:
- a module address
- a tap number
- a tap state (On/Off or Open/Closed)We could make our simple protocol something like module:0x10 message:”1=0;”. We don’t send the address over i2c but we send four bytes directly to the selected module using it’s address. Byte 1 is the tap number, 0 will close the tap and 1 will open the tap.
See our “BasicTapControl” example for the Arduino side.
/* J.A. Korten JKSOFT Educational BasicTapControl.ino Example: Arduino side i2c communication V1.0 July 12, 2017 */ #include <Wire.h> int currentTap = 0; boolean tapMoving = false; // one tap at a time unsigned long timerStart = 0; int nextTap = 0; int nextTapState = 0; boolean showDebugMsg = false; void setup() { initLEDs(); // See second tab (download our library) Wire.begin(0x10); // Pi will see the TapHat on 0x10 Wire.onReceive(receiveEvent); // register event Serial.begin(115200); // start serial for output delay(3000); if (showDebugMsg) Serial.println("TapHat Communication Example"); } void loop() { delay(100); heartBeat(); if (tapMoving) { checkTapTimer(currentTap, timerStart); } else { if (nextTap > 0) { // set tap setTapInMotion(nextTap, nextTapState); nextTap = 0; } } } void receiveEvent(int howMany) { char bufferIn[100]; int index = 0; while (Wire.available() > 0) // make sure we still can read... { char input = Wire.read(); //Serial.print(input); bufferIn[index] = input; index++; if (input == ';' || index > 4) { if (index == 5) { char tapNum = bufferIn[1]; char separator = bufferIn[2]; char tapState = bufferIn[3]; char terminal = bufferIn[4]; if (separator == ':' && terminal == ';') { byte tap = tapNum - '0'; // convert '0' to 0 byte state = tapState - '0'; // convert '0' to 0 if (state == 0 || state == 1) { // at least for now we only allow one tap changing at the time // ignoring other tap messages while tapMoving is true // we will remember one next tap change only if (!tapMoving) { setTapInMotion(tap, state); } else { rememberTap(tap, state); } } } } Serial.println(); index = 0; } } } void rememberTap(int tap, int state) { nextTap = tap; nextTapState = state; } void setTapInMotion(int tap, int state) { if (showDebugMsg) { Serial.print("Setting tap "); Serial.print(tap); Serial.print(" to state "); Serial.println(state); } setTap(tap, state); currentTap = tap; timerStart = millis(); tapMoving = true; }
In the above example we see how we could make and deal with a protocol to set taps of the TapHat board using a simple but effective protocol. You can find the entire example with the setTap implementation (see “TapControl” Tab) in our library.
The protocol consists of four bytes: “1:1;”. The first byte is the number of the tap we want to set: it can be either tap 1, tap 2 or tap 3. The colon (“:”) separates the tap number with the state. The state is the second number: 0 closes the tap, 1 opens the tap. The final token is a semicolon “;”.
Next step: 6. Tap Control from the Internet