Bug Trap v2

Home

A new year, a new module, a new bug trap :). The original bug trap was made from recycled solenoids, the new bug trap is designed from scratch, with a focus on "reliability and maintainability", but also cost :). The scenario is again that the University is overrun with cockroaches and the students are required to design an automatic bug trap. The new hardware platform is shown in figure 1, having three main components :

  1. Net: a "high" powered servo motor connected to a square net via a connecting arm. When energised the servo pushes the net down into the closed position, trapping the cockroach, otherwise it lifts the net up into the open position.
  2. Base: this section contains two infra-red illuminated LED sensor modules i.e. front and rear sensor, that detect when a cockroach is in the trap. Signals interfaced to a FPGA board via a GPIO expander module.
  3. Control panel: user console containing a RED status LED, a toggle switch and a RED push switch.

Figure 1 : Bug trap

Table of Contents

Off the shelf, in house hardware
Virtual wires
Lab 1 : combinatorial logic
Lab 2 : sequential logic
Lab 3 : simpleCPU_v1a, a software implementation

Off the shelf, in house hardware

The bug trap's sensors (infra-red sensor modules and switches) and actuators (servo and LED) are interfaced to the FPGA using an PCF8574 I2C GPIO expander (Link), shown in figure 2. This was partly due to a need to reduce the size and thickness of the connecting cable, but mainly due to the the limited IO lines on the FPGA board used, we bought the wrong FPGA board :). Note, to reduce construction time this hardware is based on off-the-shelf Arduino modules.


Figure 2 : GPIO expander

The pin-outs are:

The acrylic base template and the 3D printed elements were designed in openScad, shown in figures 3 and 4. Note, the 3D printed base is used to mount / hold in place the various modules i.e. recessed inserts, owing to lack of mounting holes on the GPIO expander PCB etc. The model files can be downloaded here: (Link).

Figure 3 : Base

Figure 4 : 3D models

To reduce the amount of wiring needed to connect the various sensors and actuators to the GPIO expander, i made a small patch board as shown in figures 5 and 6. Plug J2 connects to the I2C expander, J5 connects to the servo. Plug J1 and J2 connect to switches, JP6 to front panel LED. Plug J3 and J1 connect to the infra-red sensor modules.

Figure 5 : interface circuit


Figure 6 : Interface PCB

Virtual wires

The aim of the practicals based on this hardware is to demonstrate the operation of basic logic gates, their functions and how these can be combined to implement different components i.e. the fundamental building blocks of a computer. In the previous bug trap labs this hardware was constructed using TTL gates (Link). With the change of curriculum we no longer teach hands-on electronics, therefore, i shifted logic gate teaching into an FPGA. Students can design and implement logic circuits as schematics, these are then synthesised and uploaded into the FPGA for testing. The top level schematic shown in figure 7, constructed from three components:

  1. Bug_Trap_Controller : a combinatorial logic circuit developed in the practical, processing the input sensor data to control output actuators:
  2. Virtual_Wires : the seven signals controlling the bug trap (listed above) are not directly connected to the FPGA board as individual wires, rather signals are transferred between the FPGA board and the bug trap hardware using a serial Inter IC Communications (I2C) Bus, significantly reducing the number of wires in the white connecting cable. Note, the reason for this abstraction was due to limited IO lines on the FGPA board. This functionality is not directly visible to the bug trap controller. In addition to implementing this communications link this component also updates the seven segment LED display with the status of these signals.
  3. Clock_Divider : the FPGA board has an on board oscillator producing a 10MHz clock. This is divided down to a slower frequency to produce a 1Hz clock on the CLK_OUT pin. This signal will be used later to control the servo motor's position and the LED.

Figure 7 : top level schematic

To communicate data to and from the hardware a PicoBlaze system has been constructed and is integrated into the design using the virtual_wires component. This system provides the four inputs (pio_F_o) to the bug_trap_controller schematics and sends its two output (pio_F_i) signals to the hardware across the I2C bus shown in figure 8. The internals of the PicoBlaze system are shown in figure 9. Note, this system is used as a "black-box" component in the practical i.e. students only need to implement the control logic in the bug_trap_controller schematic.

Figure 8 : I2C data packet

Figure 9 : PicoBlaze system

Lab 1 : combinatorial logic

This first lab focuses on basic logic gates and simple combinatorial logic circuits. Therefore, the first bug_trap_controller is the simplest possible solution, only using the red push button as shown in figure 10, directly controlling the servo and LED. A short video is available here: (Link). The purpose of this design is to allow an initial test i.e. do the LED and servo work. With any hardware there is a chance that things will break, plugs fall out, wires break etc. Things only work perfectly in simulations :).

Figure 10 : Manual mode only

The second bug_trap_controller uses the infra-red sensors as shown in figure 11, a short video is available here: (Link). Again a chance to test the hardware i.e. the sensors / adjust their sensitivity, and to see if anyone can spot the NAND gate, and understand why we have so many buffers :)

Figure 11 : Automatic mode only

The third bug trap now introduces the main design elements of this lab, how to combine the previous auto and manual modes, how to convert the pseudo code as shown in figure 12 into a combinatorial logic circuit.

Figure 12 : Bug trap control rules

To combine the automatic and manual control rules the toggle switch is used to select between the two behaviours i.e. a MODE switch, with the selected mode being indicated by the LED:

These control rules can be "rephrased" as shown in figure 13, or as the truth table as shown in figure 14, the aim here is to get across the ideas of basic logic functions, and that these can then be used to implement functional systems in the real world i.e. an AND gate is more than Boolean algebra.

Figure 13 : Updated control rules

The twist in the design is that students typically infer positive logic when reading these rules i.e. assume that when the FIRE button is pressed its associated signal will output a logic 1 else a logic 0. However, this is not the case. Only the actuators use positive logic, all sensors/switches use negative logic, are active low, as shown in the truth table in figure 14. A sensor's TRUE state is represented by 0V, the FALSE state is represented by +5V. Why? Answer, it made the hardware/electronics easier to build and it teaches students not to make assumptions, always check, check and check again :).

Figure 14 : Truth tables

The rules defined by this truth table can be implemented using the logic circuit shown in figure 15.

Figure 15 : Control logic

A short video of the trap implementing the manual and automatic modes is available here: (Link)(Link).

Figure 16 : Testing, manual mode (top), triggered (bottom)

The fourth bug_trap_controller implements the manual and automatic modes, but also uses the infra-red sensors to detect the size of the bug. In automatic mode if the bug is small and only triggers one sensor the trap is triggered lowering the net, holding the bug. However, if the bug is larger, or tries to push through the trap and triggers both sensors the trap enters "persuade" mode, repeatedly hitting the bug. The pseudo code for this new behaviour is shown in figure 17.

Figure 17 : Auto, Manual and Persuade rules

This controller could be implemented in a number of different ways, but to start to introduce hierarchical design / component reuse etc, they are asked to implement this system using bit multiplexers, as shown in figure 18. Then complete the circuit shown in figure 19.

Figure 18 : bit multiplexer, symbol (left), schematic (right)

Figure 19 : bit multiplexer based solution

One possible solution is shown in figure 20. To state the obvious its not a very good solution :), lots of redundant elements that can be removed. However, the intention of using this approach is to make the link between the IF-THEN-ELSE statements in pseudo code and implementing these in hardware as multiplexers (MUX) i.e. each IF is a MUX. This simple solution then introduces the ideas of logic minimisation, optimisation i.e. the realisation that in logic design you can implement a solution that contains redundant components e.g. MUX_2B, that can then be removed. A short video is available here: (Link).





Figure 20 : Auto, Manual and Persuade mode, schematic (top), simulation (bottom)

Lab 2 : sequential logic

In lab 2 we induction memory elements i.e. flip-flops to our digital design toolkit. To support this the back story is updated, the cockroaches have evolved, they have learnt to only partially enter the trap, if the trap then closes they can now pull themselves out i.e. wriggle backwards. To allow the operator to detect when this has occurred each trap needs to remember if either of the sensors have been triggered during the night. We need some memory devices, Flip-Flops :). Note, the secondary aim of this lab is to introduce the final set of components needed to build the simpleCPU processor in lab 3 i.e. logic + memory = computer.

We start with the simplest flip-flop, a set/reset (SR) flip-flop.



Figure 21 : SR flip-flop

This circuit can be converted into the component: SR_FF, and added to the existing Automatic-only bug trap controller shown in figure 11, the resulting solution is shown below (figure 22). Now when a bug enters the trap the SET lines on the SR flip-flop is toggled, setting the Q output to a logic 1, energising (turning on) the LED. Unlike the previous Automatic-only solution, now when the bug leaves the trap the LED will remain on until the RESET lines is pressed i.e. the RED push button. A short video is available here: (Link).

Figure 22 : automatic bug trap, with bug detected LED

The back story continues :). Unfortunately the bug traps have proven too “effective” and a number of operators have had their fingers crushed whilst trying to bait this trap. Therefore, the front panel toggle switch will now be used as an enable (safety) switch :

To indicate the trap status the LED function will also be updated :

This behaviour can be described by the rules shown in figure 23.

Figure 23 : New and improved, safe rules

The flashing functionality can be implemented in a number of different ways, but to introduce a new flip-flop the solution used is based on D-type flip-flops, as shown in figure 24. Note, this is also the primitive flip-flop element used in an FPGA slice i.e. default building block within the FPGA.

Figure 24 : D-type Flip-flop

To minimise the size of the circuits that the students needed to draw the top level schematic provides a 0.8Hz clock, sourced from the on-board oscillator. To minimise the complexity of the circuit used to generate the flashing / alternating signal, a simple ring counter is used, as shown in figure 25. This circuit is a one-hot counter i.e. counts from 0 to 2 using a one-hot representation. Therefore, if the LED is connected to any of its outputs, the LED will turn on for one clock cycle and off for two clock cycles i.e. on for approximately 1 second and off for 2 seconds.



Figure 25 : Ring counter, schematic (top), simulation (bottom)

Again the ring counter schematic can be converted into a component: ring_counter_3, and added to the bug trap controller as shown in figure 26. A short video is available here: (Link).

Figure 26 : New and improved, safe bug trap controller

The back story evolves again :), to "counter" the new breed of super cockroaches (the ones that can wriggle backwards) the trap's control rules have again been updated, as shown in figure 27, such that the net is only closed when the cockroach has been in the trap for approximately 4 seconds. In the previous version, the trap closes too early, such that the cockroach is only be partially in the trap i.e. the net only traps its head. Therefore, delaying the trigger allows the cockroach time to move into the middle of the trap and to start eating the bait, such that when the net closes it captures the whole cockroach.

Figure 27 : New wait and see rules

To implement this delay the 0.8Hz clock is used to clock a binary counter i.e. if the count value is allowed to count up to 5 a four second delay will have elapsed. This binary counter can be implemented in a number of different ways, but to show some component reuse it will be constructed from components developed in other labs i.e. a ripple adder and a registers, as shown in figure 28.

Figure 28 : binary counter

Again, this schematic can be converted into a component: delay_4_sec, and added to the previous bug_trap_controller schematic, as shown in figure 29. A short video is available here: (Link).



Figure 29 : New wait and see rules schematic (top), simulation (bottom)

Lab 3: simpleCPU_v1a, a software implementation

The third lab in this series replaces the hardwired bug trap controller i.e. the applications specific hardware, with a general purpose processor. The aim here is to show the flexibility of moving functionality into software, and to also highlight the hardware costs in doing this. Note, also the processing performance costs in doing this i.e. time. The processor used is the simpleCPU_v1a that is discussed and designed in supporting lectures. For more information refer to: (Link). The hardware used to implement this processor is derived from the components used to construct the previous bug trap i.e. logic + memory = computer. The top level schematic of the new computer controlled bug trap is shown in figure 30.

Figure 30 : computer controlled bug trap

Inside this top level component is the simpleCPU_v1a processor, memory and general purpose input/output ports (GPIO), as shown in figure 31. Note, this design has two GPIO ports: A and B, giving 16 input lines and 16 output lines, this is a lot more IO than we need for the bug trap controller, but was included to make a more interesting memory map.

Figure 31 : computer architecture

The internal architecture of the simpleCPU processor is shown in figure 32.

Figure 32 : simpleCPU_v1a architecture

The GPIO lines are memory mapped into the top of the processors address space as shown in figure 33. To control the bug trap the program needs to access the four inputs (2 x sensors + 2 x switches) and control the two outputs (LED + servo). These 6 GPIO lines are connected to port A, as listed in figure 34.

Figure 33 : computer controlled bug trap memory map

Figure 34 : port A pin assignment

To control the bug trap the following code can be used to re-implement the previous hardwired control rules i.e. Auto, Manual and Persuade (stamp) modes. The simulation of this new system is shown in figure 35.

DESCRIPTION                 ASSEMBLER CODE
-----------                 --------------

IF (AUTOMATIC)              start:
THEN                            move 0x00
  TURN OFF LED                  store 0xFC
  IF (LARGE)
  THEN                      loop:
    STAMP ON BUG                load 0xFC
  ELSIF (SMALL)                 and 0x08
  THEN                          jumpnz manual
    CLOSE TRAP                 
  ELSE                      auto:   
    OPEN TRAP                   move 0xFF    
  ENDIF                         subm 0xFC
ELSE                            and 0x06 
  TURN ON LED                   jumpz start
  IF (FIRE)                     sub 0x06
  THEN                          jumpz large 
    CLOSE TRAP                     
  ELSE                      small:          
    OPEN TRAP                   move 0x01
  ENDIF                         store 0xFC
ENDIF                           jumpu loop
                               
BIT  FUNCTION               large:             
-------------                   move 0x00    
0    FIRE                       store 0xFC       
1    SENSOR1                    load 0xFC                           
2    SENSOR2                    and 0x06
3    MODE                       jumpnz loop 
4    OSC 
                            waitLow:
                                load 0xFC
                                and 0x10
                                jumpz waitLow
                                move 0x01
                                store 0xFC 

                            waitHigh:
                                load 0xFC
                                and 0x10
                                jumpnz waitHigh
                                jumpu large 

                            manual:
                                load 0xFC
                                and 0x01
                                jumpz fire 

                            reset:
                                move 0x02
                                store 0xFC
                                jumpu loop 

                            fire:
                                move 0x03
                                store 0xFC
                                jumpu loop 

Figure 35 : computer controlled bug trap simulation

A further improvement to this system is the development of a high level, application specific language i.e. a set of high level instructions designed for bug trap related applications. This can be implemented in a number of different ways, however, to simplify software development the M4 pre-processor was used (Link), allowing blocks of assembly code to be replaced with a single high level instruction, as shown below:


define(GPIO, `0xFC')

define(goto, `jumpu $1')

define(turnOnLED, `load eval(GPIO+1)
and 0xFD
add 2
store GPIO')

define(turnOffLED, `load eval(GPIO+1)
and 0xFD
store GPIO')

define(closeTrap, `load eval(GPIO+1)
and 0xFE
add 1
store GPIO')

define(openTrap, `load eval(GPIO+1)
and 0xFE
store GPIO')

define(buttonPressed, `load GPIO
and 0x01
jumpz $1')

Using these macros an assembly code implementation can now be re-implemented using macros, as shown below:

DESCRIPTION             ASSEMBLY CODE               MACRO IMPLEMENTATION
-----------             -------------               --------------------

IF (FIRE)               start:                      start:
THEN                        load 0xFC                   buttonPressed fire
  TURN ON LED               and 0x01                
  CLOSE TRAP                jumpz fire              reset:
ELSE                                                    turnOffLED
  TURN OFF LED          reset:                          openTrap
  OPEN TRAP                 move 0x03                   goto start
ENDIF                       store 0xFC                  
                            jumpu start             fire:
                                                        turnOnLED          
                        fire:                           closeTrap
                            move 0x00                   goto start
                            store 0xFC
                            jumpu start

In addition to these simple macros, more complex behaviours can also be implemented e.g. stamp on bug, as shown in the macro below. The variables LOW_COUNT and HIGH_COUNT are assigned fixed addressing within the M4 macro script. This delay function will be called within the stampOnBug macro twice, therefore, it is passed the Ids “1” and “2” to ensure unique label names. The lonDelay macro is called 10 times using the LOOP_COUNT variable to produce the 0.75 second delay. Trap controlled by the openTrap and closeTrap macros.


define(LOW_COUNT, `0xE0')
define(HIGH_COUNT, `0xE1')
define(LOOP_COUNT, `0xE2')

define(longDelay, `move 0
store LOW_COUNT
store HIGH_COUNT
innerLoop$1:
load LOW_COUNT
add 1
store LOW_COUNT
jumpnz innerLoop$1
outerLoop$1:
load HIGH_COUNT
add 1
store HIGH_COUNT
jumpnz innerLoop$1'
)

define(stampOnBug, `closeTrap
move 10
store LOOP_COUNT
closedWait:
longDelay( 1 )
load LOOP_COUNT
sub 1
store LOOP_COUNT
jumpnz closedWait
openTrap
move 10
store LOOP_COUNT
openWait:
longDelay( 2 )
load LOOP_COUNT
sub 1
store LOOP_COUNT
jumpnz openWait'
)

Creative Commons Licence

This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.

Contact email: mike@simplecpudesign.com

Back