Part 1 of this post is the implementation of a full duplex master/slave network with one master and one slave. Four switches at the master controller control four LEDs at the slave controller and four switches at the slave controller control four LEDs at the master controller. This network uses the same protocol as the half duplex network I use to control the LED lights in my solar powered home lighting system. One of the biggest regrets I had with that design was the half duplex network because it limited the master controller slave polling rate. This full duplex network has a 1mS polling rate.
I used four MAX487 transceivers for the breadboard because I had them on hand. I’ve included a second schematic for the MAX488(meant for full duplex and you only need 2). I’ve tested the network as shown (with the MAX487) to a distance of 80 feet with no line termination resistors but I am sure it would operate at much greater distances.
In part 2 I will connect the network with one master and two slaves to demonstrate how the network can be used to control LED lights by reading slave switches, motion sensors, etc. and then control slave connected LEDs all with control logic running in the master controller. I will post part 2 as a modification to this post.
The protocol executes a transaction between master and addressed slave that is always initiated by the master. A transaction is one of two types, command or information. In a command transaction the master sends an object to the addressed slave and in an information transaction the master requests an object from the addressed slave. An object is one byte of data. This protocol can support a maximum of 96 objects. To begin a transaction the master increments to the next polled address in the range of 20h to 7Fh. Object definitions are stored in EEPROM. An object definition consists of the transaction type and SD_Address (SD = source/destination). SD_Address = byte@EEPROM for the polled address. Then type = SD_Address bit 7. SD_Address bit 7 is then cleared and SD_Address = RAM bank0 location for the source or destination depending on type (1=command, 0=information). The PIC16F690 USART can transmit and receive 9 bits. The 9th bit is used to distinguish between addresses and data (1=address, 0=data). You can see this protocol in the flowcharts for the master and slave communications state machines.
Attached are the following files;
Schematic using MAX487 transceivers as pdf
Schematic using MAX488 transceivers as pdf
Master FD Network code as asm *
Slave FD Network code as asm *
Switch debounce flowchart as pdf
Master FD Network CSM State 1 flowchart as pdf **
Master FD Network CSM State 2 flowchart as pdf
Master FD Network CSM State 3 flowchart as pdf
Slave FD Network CSM State 1 flowchart as pdf
Slave FD Network CSM State 2 flowchart as pdf
* Columns may not appear as intended if not viewed in MPLAB editor.
** CSM = Communications State Machine.
Part2
In Part 2 I want to connect two slaves to the master controller. In the solar powered LED lighting system I designed for my home, I use a circuit I call a PDAC to act as a slave or master depending on how it is programmed. I have multiple slave PDACs around the house reading touch switches and motion sensors and reporting the state of those switches and sensors to the master when polled and then receiving LED on/off commands from the master to control the LEDs connected to them. All of the control logic including on times for automatic LED turn off when there is no motion (a must in a solar powered system) is done in the master controller. Only the master PDAC needs to be reprogrammed to change this logic. Note this also means any switch or motion sensor anywhere in the house can control any LED anywhere in the house. At times this is convenient when one slave PDAC is closer to a switch/sensor or LED during installation.
We need to change the schematic used in Part 1. Now we need the MAX487 or if you want the transmitter and receiver in one package the MAX489. I want to use the circuitry I already have as the two slaves, Slave1 and Slave2. I want to connect the receiver from Slave1 to the receiver from Slave2 and then that receive bus to the Master transmitter. No problem with that. Now I want to connect the transmitter from Slave1 to the transmitter from Slave2 and then that transmit bus to the Master receiver. Now I have a problem. Even though only one Slave transmitter will be transmitting at a time, the other transmitter will be trying to hold the transmit lines in an idle state and the two will wind up fighting each other. That is called contention and is not what you want. With the MAX487 we can turn the transmitter on and off with a control line and we will do that with PIC pin RB6. Now only the transmitter sending data will be on the line and there is no contention. Now I add another PIC for the Master and another transmitter and receiver and I have the circuit I need.
I settled on a 1.2mS Object polling rate. It will take about 115mS to poll all 96 Objects (if used) and allowing for two times around (first time to get switch/sensor data and next time to send LED commands) that will still yield a response time of approximately 1/4 second. While on the subject of Object polling, it is possible to receive multibyte data by simply making each byte an Object. I have a real time clock on the network in my LED lighting system and it reports the time of day as total minutes. The real time clock maintains that as a 16 bit (2 byte) word. The Master simply polls two Objects from the real time clock to get the word. In this case we have a number that can roll over after polling the first Object and before polling the second Object. So the master polls the two Objects twice, stores the two words and compares them. If the words are the same, there was no roll over and the number is good.
Note the Slave assembly code is identical for Slave1 and Slave2 except for the address min and address max constants. I have to change the address max in the Master and add all four objects (two for each slave) to the object definitions in eeprom and list all four objects in bank0 ram and I’m ready to write LED control logic code in the Master controller. In the Master code, Slave1 will be Object01(Switches and Sensors) and Object02(LED on/off commands) and Slave2 will be Object03(Switches and Sensors) and Object04(LED on/off commands).
I will use the same control logic for each slave. Switch1 (PIC RC04) will be the on/off switch (0=on) and Switch2 (PIC RC05) will be the motion sensor (0=motion). A timer will control the LEDs. If Switch1 is off, I zero the timer. If Switch1 is on and there is motion, I load the timer with LED on time. The LEDs are on as long as the timer is not 0. The LEDs will stay on for the on time when you leave the room and if you return before the time out will stay on. You can see this logic in the included flow chart. Try changing the Switch assigments (Slave2 switch turns on/off Slave1 LEDs etc) or add your own logic. How would you change the logic in the Master controller to control the LEDs with momentary push buttons at the slaves instead of the toggle switches (the slave code is not changed)?
Attached are the following files;
Master and 2 Slaves FD Network schematic as pdf
Master2 FD Network code as asm *
Slave1 FD Network code as asm *
Slave2 FD Network code as asm *
FD Network Slave CSM WTC State1 flowchart as pdf***
FD Network Slave CSM WTC State2 flowchart as pdf***
FD Network Slave CSM WTC State3 flowchart as pdf***
Slave1 and 2 LED control flowchart as pdf**
* Columns may not appear as intended if not viewed in MPLAB editor.
** Code runs in Master
***CSM = Communication State Machine WTC = With Transmitter Control