SlideShare a Scribd company logo
1 of 75
Download to read offline
Indiana University - Purdue University Fort Wayne
Department of Engineering
ECE405 - ECE406
Capstone Senior Design Project
Report #2
Project Title: Low-Cost Reconfigurable Modular Robots
Team Members: Timothy Boles
Christopher Coffee
Justin Galvan
Steven Groff
Faculty Advisor: Yanfei Liu, Ph.D
Date: May 4, 2015
2
Table of Contents
Acknowledgements ........................................................................................................................4
Abstract.........................................................................................................................................5
Section I: Problem Statement.........................................................................................................6
1.1 Requirements and Specifications..............................................................................................7
1.2 Given Parameters ...................................................................................................................7
1.3 Design Variables: ...................................................................................................................7
1.3.1 Hardware:........................................................................................................................7
1.3.2 Software:.........................................................................................................................7
1.3.3 System Conditions: ..........................................................................................................8
1.4 Limitations and Constraints: ....................................................................................................8
1.5 Additional Considerations: ......................................................................................................8
Section II: Detailed Design.............................................................................................................9
2.1 Functional Overview of Module.............................................................................................10
2.1.1 Overall Overview...........................................................................................................10
2.1.2 Operating Process Overview ...........................................................................................10
2.2 Controller Board...................................................................................................................12
2.2.1 Microcontroller..............................................................................................................14
2.2.2 Current Sensor...............................................................................................................15
2.2.3 Voltage Regulators.........................................................................................................17
2.2.4 DC Motor Driver............................................................................................................18
2.2.5 Magnetic Encoder for DC Motor .....................................................................................19
2.3 Wireless Communication ......................................................................................................19
2.4 Motors and Battery...............................................................................................................20
2.4.1 Picking the Motors and Batteries .....................................................................................20
2.4.2 Power Calculations.........................................................................................................22
2.5 Casing.................................................................................................................................22
2.5.1 Casing Overview............................................................................................................22
2.5.2 3-D Printer Settings........................................................................................................26
2.6 Changes to the Initial Design: ................................................................................................27
3
2.7 Final Prototype Design..........................................................................................................29
Section III: Prototype Construction .............................................................................................30
3.1 Prototype Construction..........................................................................................................31
3.1.1 Casing and Brackets: ......................................................................................................31
3.1.2 Module Protoboard:........................................................................................................34
3.1.3 Controller Protoboard:....................................................................................................36
3.1.4 Assembling Process:.......................................................................................................39
3.1.5 Software Development: ..................................................................................................42
3.2 Prototype Cost Breakdown ....................................................................................................45
Section IV: Testing ......................................................................................................................47
4.1 Testing Requirements and Methods........................................................................................48
4.1.1 Three Types of Motion: ..................................................................................................48
4.1.2 Movement Accuracy: .....................................................................................................49
4.1.3 Battery Lifespan:............................................................................................................50
4.1.4 Prototype Weight: ..........................................................................................................50
4.1.5 Wireless Communications Distance: ................................................................................50
Section V: Conclusions and Recommendations.............................................................................51
5.1 Conclusions .........................................................................................................................52
5.2 Recommendations ................................................................................................................52
Appendix A..................................................................................................................................54
Appendix B: Source Code for Module..........................................................................................58
Appendix C: Source Code for Controller .....................................................................................64
4
Acknowledgements
We would like to express our appreciation to our advisor Dr. Yanfei Liu for allowing us to participate in
this project. Without her guidance and direction this project would not have been possible.
We would also like to thank Dr. Carlos Pomalaza-Ráez and Bill Westrick whose knowledge has been
invaluable during this project. With their on-hand experience they greatly added to the quality and
feasibility of the project.
A special thanks is also needed for Dr. Zhuming Bi and Alfonso Costas who have been extremely helpful
and available for all questions regarding the mechanical engineering aspects of this project.
The group would also like to thank Bob Tilbury for his help with the PCB design as well as operating the
3D printers to print our parts.
Finally, we would like to thank the IPFW Engineering Department for sponsoring this project.
5
Abstract
An emerging topic in science today is modular technology. Modular robots provide a wide range of uses
in many different areas. Industrial robots assemble the things we use every day, and some mobility robots
help navigate and explore rough terrain. Applying the modular aspect on the robot allows for even more
flexibility in use.
The focus of this project is to design a class of modular robotic systems that can achieve different forms
of movement. This modular robotic system could be used in future robotics courses as a teaching tool for
future engineers in an undergraduate or graduate program. These robots can come in different forms
involving several small modules attached together to form a working and moving robot. This type of
design requires not only a mechanical flow between modules but also a steady electronic communication
that gives modules the information they need in order to move in the correct manner. The system will be
measured by the ability to be reprogrammed, it should have its own power supply so movement is not
restricted, this power supply must be rechargeable, the modules should be interchanged easily, and be
able to move in a variety of ways.
After developing a design for a modular robotics platform in the Fall 2014 semester, that design was
attempted to be completed in the Spring 2015 semester. Although the design was subjected to several
modifications, a functional low-cost reconfigurable modular robotics platform was developed and several
design aspects were tested to verify success. Because the project passed all of the subjected tests, it was
determined that the implemented design met the requirements and specifications of this project.
6
Section I: Problem Statement
7
1.1 Requirements and Specifications
The following requirements and specifications must be met for a successful project:
➢ Central Control Unit - Each module must have a central control unit, such as an Arduino, this unit
must be re-programmable, this will allow for operational changes to be made to the modules.
➢ Power - The modules must be powered by a non-restricting and rechargeable power supply. This
is to remove the need to be attached to an outlet. This will allow for a greater range of motions
and makes the modules more self-contained.
➢ Sensors - The modules must have some type of spatial awareness, this is to prevent the modules
from running into object and damaging themselves.
1.2 Given Parameters
The following parameters are given in the design of the modular robotics system:
➢ Budget - The allotted budget for the project was $1000, given by the IPFW Department of
Engineering. The group must spend less than or equal to this $1000.
➢ Mobility - The modular robots must be able to implement at least three different methods of
motion. These different types of motions will be accomplished through different configurations
of the modules.
➢ Sensors - Two types of spatial awareness are needed to give better control to the modules and
prevent the modules from damaging themselves.
➢ Configurations - Each configuration must consist of at least two distinct modules. A single
module will not be considered its own unique configuration.
1.3 Design Variables:
1.3.1 Hardware:
➢ Module Construction Materials - Parts such as module connectors and electronic housings should
be manufactured through common processes such as plastic injection molding or 3D printing,
more common components could be ordered.
➢ Module Communication Medium - Wired or wireless communication between modules with a
standardized connector.
➢ Central Control Unit - The central controller unit of the system will operate on an embedded
system platform already available for purchase, i.e. Arduino.
1.3.2 Software:
➢ Communication Framework - A communication framework needs to be created to allow for
standardized communications for the central control unit to various modules and inter-module
communication.
8
➢ Module Communication Protocol - Depending upon the choice of communication medium, a
variety of short-ranged wireless protocols can be used such as Bluetooth, infrared (IrDA), or Wi-
Fi.
1.3.3 System Conditions:
➢ Module Timing - The modules will need to be in sync to function properly, this is especially true
for movement and communication purposes between multiple modules.
1.4 Limitations and Constraints:
➢ Durability - The modular robot is expected to move along the floor and various surfaces. It
should be durable enough to resist wear from movement across these surfaces. The connection
between modules must be durable enough to withstand the strain of moving.
➢ Materials - As this robot may need to be handled for swapping out pieces, the rechargeable
battery packs, or changing the code, it is of the utmost importance that the robot is safe to handle.
1.5 Additional Considerations:
➢ Other types of modules (Audio, LEDs) - This would add even more features that would be
modular attachments to further increase the number of possibilities in setups.
➢ Robot Controller - This could be a way for the user to control the robot without inputting or
uploading new code. This could be in the form of a wired or wireless controller, this would be
optimal for demonstrations to users who don’t understand code.
➢ Programming Interface - Utilizing a form of wireless communication would allow the modules of
the robot to be updated without the need to be physically connected to a computer.
9
Section II: Detailed Design
10
2.1 Functional Overview of Module
2.1.1 Overall Overview
Throughout the designing of the modular robotic system the given parameters and design constraints were
kept in mind when choosing components. Movement, weight, and size were a huge focus when choosing
parts. This led the components of the modules to be smaller and more compact, as well as power and
resource efficient. Cost was another area of concern because smaller but more powerful components tend
to cost more. These constraints and parameters led to the design of a module where some dynamics in
movement were sacrificed in order to get a compact and sufficient base module design.
In the chosen concept a single base module is used. This base module contains two motors and all the
electronics necessary to operate those motors as well as communicate to a master hub. Each module
casing has magnetic connections on all sides so that subsequent modules can be added to create a
cooperative and moving system. In order to get necessary module movement, two motors were needed. A
servo motor is used to create a joint/elbow like motion while a DC motor is used to create a purely
rotational motion. A microcontroller is used to run as well as regulate the motors along with some other
electronics. All these elements create a single base module with two dynamics in its motion.
2.1.2 Operating Process Overview
Figure 1 is a flow diagram that illustrates the process that each module goes through in order to execute a
command. Here the message will be transmitted from a transceiver that is connected directly to a
computer. This computer will send out the commands for each module and a transceiver inside the
module will check them. If the message has pertinent information, like a command or request, then the
module in question will continue with the information and execute all the necessary steps. Most messages
will be command messages that the micro-controller in the module will pass to the motors making them
move in some way.
11
Figure 1: Overview for the per module process.
12
2.2 Controller Board
In keeping with the idealistic modular approach with the robot, each module of the system will have a
self-contained controller. Utilizing a single PCB we will be able to integrate all electronics, chips, and
boards onto a single component that would then be fastened to the module casing. The main components
of the controller will include the following:
● Arduino Pro Mini 328 Microcontroller
● 595-INA169NA/3K Current Sensor
● 3.3 V - 595-UA78M33CDCYG3 Voltage Regulator
● LT1085CM Adjustable Voltage Regulator
● Dual TB6612FNG (1A) Motor Driver (DC Driver)
● NRF24L01+ 2.4GHz Wireless RF Transceiver
● Magnetic Encoder for Micro Metal Gearmotors (connected to DC motor)
A high-level block diagram for the controller board can be seen in Figure 2 while Figure 3 shows an
overall schematic for the connections between these electronics.
Figure 2: High-level block diagram for the Controller board.
13
Figure 3: Overall schematic for the Controller board.
Two different approaches will be used to control each of the motors. First, a motor driver will be
purchased to control the DC motor. This driver allows for a PWM signal to amplify the current available
to the motor. Two other inputs allow for the rotational direction of the motor to be controlled or for the
motor to be stopped. These pins will be numbers D4 and D5 on the Arduino board. The output of the DC
motor driver will then connect to the DC motor and to the DC motor encoder. This digital encoder will
allow for the position of motor to be measured up to a resolution of 1/8th of a rotation, outputting the
current position to pins D7 and D8 of the microcontroller. Two current sensors are placed on the Vcc pin
of the DC motor to detect a stall current regardless of the direction in which the motor is spinning. If a
stall is detected on pins A1 or A2 of the Arduino board, the controller will shut off power to the motor.
14
Additionally, the Servo motor will be controlled by another Pulse Width Modulated signal, generated by
the D9 pin on the microcontroller. This PWM signal will control the angle at which the servo motor is
positioned. The LT1085ISX Adjustable Voltage Regulator was selected to achieve this motor’s operating
voltage of 6 volts. Again, a current sensor is placed in series with this regulator to detect the 0.8 amp stall
current of the servo motor. The stall current signal from the current sensor will be read by the A0 pin of
the Arduino. A photo of the Arduino, including the pin layout, which will be used can be seen in Figure
4.
Figure 4: Arduino Pro Mini board from Sparkfun.com.
2.2.1 Microcontroller
The used microcontroller for the Controller board will be an Arduino Pro Mini. The particular board is a
3.3V Arduino running at 8MHz. It contains a built in voltage regulator allowing the use of a raw voltage
input. In order to save size the board does not containing any connectors (all connections must be
soldered on) or any USB/ programming peripherals. This allows for a completely minimalist
microcontroller, perfect for the size constrained modules. The schematic for the Arduino can be seen in
Figure 5.
15
Figure 5: Schematic for the Arduino Pro-Mini 328 Microcontroller
This will be our main brain of each module and will be interfaced in some way to all of the components
going inside. The commands for the microcontroller will be programmed in C/C++ and the program will
be loaded with an FTDI basic Breakout board with USB connection before it is placed on the main PCB
controller board. Using the digital SPI ports it will control the wireless communication via a transceiver.
It will also control both motors whether directly with the servo or through a motor driver with the DC.
2.2.2 Current Sensor
These components are necessary for monitoring the limits of the robotic system. With loaded motors and
voltage sensitive components controlling the current and voltage is a necessity. In the chosen concept, a
current sensor is needed for each motor. With one of these sensors in place the module is able to detect
when the motors are reaching rated stall current and shut off the necessary components so that none of the
motors or electronics are harmed. The voltage regulators are necessary in order to ensure that the voltages
supplied to the electronics such as the motor driver and motors are never exceeding the rated.
16
Figure 6 shows the schematic of the current sensors. The
selected current sensors detect a small voltage drop across a
shunt resistor then converts the detected voltage drop to another
voltage via an operational amplifier. According to the datasheet,
this sensor works best when detecting a drop of 0.5 volts or less.
Another determining factor to using this chip was that the
analog inputs of the microcontroller can only detect up to 3.3
volts. Keeping these values and the stall currents of the motors
(0.8 A for the Servo motor and 1.6 A for the DC motor) in
mind, a variation of Ohm’s Law, seen in Equation 1, and
Equation 2 (provided by the datasheet) were used to calculate
the necessary resistors.
0.5 𝑉 ≥ 𝐼𝑆𝑆𝑆𝑆𝑆 ∗ 𝑅𝑆 (1)
𝑉𝑂 =
(𝐼𝑆𝑆𝑆𝑆𝑆∗𝑅𝑆∗𝑅𝐿)
1 𝑘𝛺
(2)
This calculation yields resistor values of RS = 0.4 Ω and RL = 10.2 kΩ for the Servo motor and RS = 0.4 Ω
and RL = 5.1 kΩ for the DC motor. In these equations, RS is the shunt resistor and RL is an external
resistor used to adjust the needed output voltage. Because RS for the Servo motor is twice that of RS for
the DC motor, two 5.1 kΩ resistors will be placed in series to achieve the calculated 10.2 kΩ resistance to
reduce the cost of the design. Equation 3 and Equation 4 detail the power calculations that were
performed to ensure the resistors could perform as needed.
𝑃𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 = 𝐼𝑆𝑆𝑆𝑆𝑆
2
∗ 𝑅𝑆 (3)
𝑃𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 =
𝑉𝑂
2
𝑅𝐿
(4)
Table 1 shows the results of these calculations. From this table, it can be seen that RS will need to be able
to handle at least 1024 mW of power consumption and RL will need to handle up to 2.09 mW of power
consumption. The selected resistors for both RS and RL can handle 2 W of power consumption.
Table 1: Power Consumption for Current Sensing Resistors
Servo Motor DC Motor
RS 256 mW 1024 mW
RL 1.04 mW 2.09 mW
Figure 6: Operational schematic for
the current sensor.
17
2.2.3 Voltage Regulators
A 3.3 volt and a 6 volt voltage regulator will also be implemented in each board to supply the transceiver
and Servo motor respectively. A voltage regulator is not needed for the DC motor because this motor will
be implemented with a driver, which will take care of the voltage requirements. Because the power supply
in each module operates at 7.4 volts, the voltage regulator will step down the voltage to something more
useable by the servo motor or the transceiver. Another reason for their implementation is to minimize
voltage drops as motors turn on and off.
The main concern when selecting the specific voltage regulator was to ensure that they could supply
enough current. According to the transceiver’s datasheet, the maximum current needed will be 13.5
milliamps. The selected 3.3 volt voltage regulator can provide up to 500 milliamps.
To supply 6 volts and 1.6 amps to the Servo motor, a fixed 6 volt regulator could not be used. Research
showed that a cost-efficient regulator that met these
specifications was not available. Therefore, an adjustable
voltage regulator will be used. This Regulator can supply up
to 3 amps of current, well above the 1.6 amp stall current of
the Servo motor. Figure 7 shows the schematic of the
adjustable regulator. According to the data sheet, because IAdj
≤ 120 microamps, VREF = 1.25V and if R1 ≈ 100 Ω, Equation
5 could be used to determine the resistance values. From this
equation, it was determined that the resistance values needed
will be R1 = 100Ω and R2 = 380Ω.
𝑉𝑂 = 𝑉𝑅𝑅𝑅 ∗ �1 +
𝑅2
𝑅1
� (5)
A Multisim simulation for the voltage regulator was constructed in order to verify the calculated resistor
values. Figure 8 shows that the circuit generates close to the expected 6V using the resistors found from
Equation 5.
Figure 7: Operational schematic for the
adjustable voltage regulator.
18
Figure 8: Simulation for the adjustable voltage regulator.
2.2.4 DC Motor Driver
A driver board will be utilized in order to efficiently control the DC motor creating the rotational motion
of the modules. A Dual TB6612FNG (1A) Motor Driver was chosen in regards to its ease of
implementation with an Arduino. This driver board will allow the microcontroller control over the motors
direction as well as speed using outputted PWM (Pulse Width Modulation) signals with a frequency up to
100kHz. The schematic for this driver board can be seen in Figure 9.
Figure 9: Schematic for the DC motor driver (Dual TB6612FNG (1A) Motor Driver).
19
2.2.5 Magnetic Encoder for DC Motor
An encoder will be used on each DC motor. This will give the microcontroller the ability to send
commands to the DC motor (through the driver module) with feedback. For instance, a command could
be sent to the motor to turn for 5 revolutions. With the encoder, the module will be able to make counts
like this. We chose the magnetic encoder for its ability to be paired with a DC motor with a back shaft.
Although limiting the scope of DC motors that could be used in the design, the ability to have better and
more precise movement data greatly outweighed the cost. A schematic for the magnetic encoder can be
seen in Figure 10.
Figure 10: Provided schematic for the magnetic encoder board.
2.3 Wireless Communication
The modules will utilize the NRF24L01+ transceiver for wireless communication. This transceiver
module supports operating speeds up to 2Mbps as well as low power consumption. It will be implemented
into the SPI ports of the Arduino Pro Mini controller. With a transceiver inside each module of the robot,
all modules will have communication with the main controlling Arduino board (which is connected to the
programming computer).
The chosen protocol to use for the communication of the modules is a self-defined raw packet transfer.
Although there was an availability of standard wireless communication protocols such as ZigBee
(802.15.4), Wi-Fi (IEEE 802.11), and Bluetooth (IEEE 802.15.1) the raw packet transfer was found to be
sufficient in both cost and implementation.
The protocol will utilize an array of 32 bytes, not all of which will be used. The array will contain a byte
for the message type, a byte for a message ID, and 30 separate bytes containing messages pertinent to a
single module. Each module will receive the array but will only index the message type, the message ID,
and two bytes of data specific to that module. The two bytes of module specific data will then contain first
8 bits, 4 of which tell the degree of the servo motor, 1 bit for the direction of the DC motor, and 3 bits for
the speed of DC motor and then 8 more bits containing encoder count details. This will allow the servo
motor to work with a degree resolution of about 6 degrees, the DC motor to tell which direction it should
be going, 8 different speeds for the DC motor, and the number of revolutions for the DC motor. An
overview of the protocol array can be seen in Figure 11.
20
Because not all 32 bytes of the array are utilized, this protocol could very easily be expanded to work with
even more modules or more bytes dedicated to a single module. Also, it is well-known that bit errors can
occur over communication especially with wireless transmission. With so much extra room in the
communication array, encoding (such as Hamming or Convolutional encoding) could be utilized in order
to detect and correct errors. Utilizing past projects, code for this encoding and decoding is available with
the work coming from integrating the code into our protocol. Also, the chosen transceiver (NRF24L01+)
has built in CRC coding which is also used to detect and correct errors in wireless communication.
Figure 11: Overview diagram of the communications protocol.
2.4 Motors and Battery
2.4.1 Picking the Motors and Batteries
In order to select the motors and battery several factors were kept in mind; torque, voltage/current, and
weight. These motors had to be small enough to fit in the modules but strong enough to lift another
module. Since the voltage, current, and weight were a major factor it was decided to determine the
battery before the motors as the battery would have the most mass and would limit the possible motors.
After looking at various batteries and the available space it was decided that two batteries with a voltage
of 7.4V and are rated at 800mAh would be used. A charger was also found that would be compatible
with the lithium polymer batteries to recharge the batteries when needed.
A DC motor and a servo motor were then found that were small enough to fit in the design, yet strong
enough to perform the needed tasks. The DC motor has a torque of 2.16 kg*cm at 6 V and a stall current
of 1.6A. Likewise, the servo motor has a torque of 5.5 kg*cm at 6 V and a stall current of 0.8 A.
Because the DC motor focuses on the rotational motion, the calculations depend on the radius of the
object being rotated, which will be either the wheel or another module. The calculation to find the
21
amount of mass the DC is able to move for a radius of the wheel (3.81 cm) and module (5.388 cm)
connected to the DC motor be seen in Table 2. For the servo calculations it is assumed that the average
mass that the servo motor has to move will be between 3-6 inches away from the axis of rotation, as each
module is 3 inches long. The calculations for the amount of mass the servo can move at the lower end of
7.62 cm (3 in) and the upper end of 15.24 cm (6 in) can be seen in the lower half of Table 2.
Table 2: The mass calculations for the DC motor and servo motor.
Based on these measurements a module would have to have a mass of 369 grams or less for the servo to
be able to move another module. To verify these values work, a table of the masses of each component
was created, Table 3.
Table 3: The estimated mass of a single module based on components.
Motor Torque (kg*cm) Radius (cm) Mass (kg)
3.81 0.567
5.388 0.401
7.62 0.722
15.24 0.361
DC Motor
Servo Motor
2.16
5.5
22
Based on the combined mass from Table 3, both of the motors have enough torque to lift/turn an adjacent
module, which will greatly increase the mobility and connections made available when assembling
modules.
2.4.2 Power Calculations
Based on the max possible current a component will draw from the battery and voltage consumption of
the components attached to the battery it was possible to calculate a worst case power consumption.
These values can be seen in Table 4. The total power was found to be roughly 14.57 Watts and is
manageable by the batteries. Based on the batteries mAh rating of 800 mAh the batteries will last roughly
36 minutes (based on total current draw from the table). Since this is the worst case scenario it is
expected that the batteries will last much longer.
Table 4: Worst case power consumption of the module.
2.5 Casing
2.5.1 Casing Overview
The casing and parts for 3D printing were developed and modeled in SolidWorks. The casing was broken
up into different sections for printing, these sections are; the 4-sided casing, a wall insert, a casing wheel,
and plastic inserts (4 for each module). The print time for these components can be seen in Table 5. The
4-sided casing will be the largest section and will be a base for all the other parts of the casing. The wall
insert will slide into the base and connected using screws. The casing wheel will be connected on the
open top of the module, it will connect to a shaft hub that comes from the DC motor. The plastic inserts
will go in each wall and separate the magnets and sheet metal disks from the inside of the module. The
bottom of the module will not have a plastic insert as the servo motor will be using some of the space that
the insert would take up.
Component Voltage Drop (V) Amps (A) Watts (W)
DC Motor Encoder 7.4 0.060 0.444
DC Motor Driver 7.4 1.600 11.840
Arduino 7.4 0.150 1.110
6V - Adjustable Regulator 1.4 0.800 1.120
3.3 V - Fixed Regulator 4.1 0.014 0.055
2.624 14.569
Total
23
Table 5: The different components that will need to be printed per module.
The total printing time required for all the components is roughly 14.6 hours. This is with a 10% fill in
the walls of the module. For explanation purposes the top of the module will be refer to the open end
where the wheel attachment is connected. All of the electronic components will be placed on a PCB
mounted on the wall opposite of the removable wall insert. On the two walls adjacent to the electronics
the batteries will be placed, one on each side. This will help to balance the weight of the module as the
batteries are the heaviest components. The servo motor will be on the floor of the module and turn a shaft
that will be supported from a bracket. This shaft will then connect to the DC motor with a bracket, which
will connect to the shaft hub, and then onto the wheel at the top of the module. This setup can be seen in
Figure 12. Views of the other SolidWorks models (4-sided case, wheel, inserts, etc.) can be seen in
Figures 13-17. For a complete view of the 3D printed elements refer to Appendix A.
Figure 12: Overall view of the constructed module.
24
Figure 13: Overall dimension of assembled module.
Figure 14: Views showing the center of mass (purple coordinates). From the absolute center of the
module, the center of mass is X= -0.25, Y = 0, Z = 0.05.
25
Figure 15: Explosion view of DC motor assembly and wheel.
Figure 16: Explosion of the wall casing and insert.
26
Figure 17: Explosion of the servo assembly and casing.
2.5.2 3-D Printer Settings
The MakerBot Replicator 2 3-D printer will be used to create the casing and all of the plastic pieces
attached. The printer is capable of printing with a resolution of 100 microns. Figure 18 shows the settings
using the MakerBot Desktop printing software. As shown, the casing will only have a 10% fill. The
MakerBot 3-D printer uses a honeycomb filling structure and provides for very strong walls without the
need to completely fill them. Setting the casing to 10% greatly reduced the amount of used material
greatly lowering the weight and cost.
27
Figure 18: Screen capture of 3-D printer settings.
2.6 Changes to the Initial Design:
Several design changes were made to alleviate issues encountered during the implementation of the initial
concept.
1. Locking Mechanism - Due to inconsistencies in the 3D printing of the module casings, magnets
could not be reliably used to connect modules. Instead, a Velcro pattern was developed that could
perform in the same manner as the magnets as seen in Figure 19. This pattern had alternating
hook and loop structures to securely connect modules together.
Figure 19 - Alternating hook and loop Velcro pattern used for inter-module connection.
28
2. PCB to Protoboard - Development of a PCB for the modules had to be cancelled due to time
constraints. Instead, components were wire-wrapped on a protoboard. This allowed for straight
forward troubleshooting and ease of board rearrangement. During this transition, the current
sensor was removed from the board because of size restraints and inability of integration.
3. 3-D Printed Design – Changes had to be made to the casing to accommodate the protoboard.
Additional battery holders were extruded from the servo bracket and the insert wall to better hold
the batteries in place.
4. Controller Implementation - It was decided to implement a controller to ease the use of the
modules,. This decision eased development in three ways. First, code to control the modules only
needed to be re-downloaded once to the controller opposed to needing to re-downloaded to each
module. Second, the controller allowed for dynamic control of the modules instead of relying on
a preprogrammed set of instructions. Third, the controller eliminated the need for spatial
awareness sensors within each modules, as errors could be dynamically corrected by the user.
5. DC Motor Encoder - Although an encoder was integrated with each DC motor in the modules,
code to utilize the encoder was not developed for the microcontroller. It was deemed unnecessary
due to the implementation of a controller.
6. Wireless Protocol - Some changes were made in the wireless protocol. The new protocol is
outlined below:
RFRxBuffer[0] = Message type
RFRxBuffer[1] = Message ID number
RFRxBuffer[(ModID + 1) * 2] = ((servoAngle << 3)&0xF8) |
((servoSpeed << 1)&0x06) |
(dcDir&0x01);
RFTxBuffer[(ModID + 1) * 2 + 1] = dcSpeed;
RFRxBuffer[]: an array used to store the data received from the transceiver.
ModID: the ID number of the module. Each module has a unique ID which allows it to find its
data from the array. The addresses can range in value from 0 to 14 due to the transceiver only
being able to transmit 32 bytes at a time. For this project, only 24 bytes were transmitted at a
time.
servoAngle: a 5-bit variable that tells the module where to align the servo motor.
servoSpeed: a 2-bit variable that tells the microcontroller how fast to move the servo motor. It
was found at some fast speeds, the servo motor would move violently.
dcDir: a 1-bit variable used to spin the DC motor clockwise or counter-clockwise.
dcSpeed: an 8-bit variable used to determine how fast the DC motor should spin.
29
2.7 Final Prototype Design
After making the alterations mentioned above, 4 main modules and 1 backup module was developed and
can be seen in Figure 20. Each module consists of a controller board, two parallel batteries, a servo
motor, DC motor, encoder, interlocking velcro, and several 3D printed parts.
Figure 20 - A total of 4 main modules and 1 backup module (not pictured) made for this project.
30
Section III: Prototype Construction
31
3.1 Prototype Construction
3.1.1 Casing and Brackets:
The reconfigurable module robots are three inch cubes. The casing and brackets were 3D printed using a
makerbot replicator 2. They were printed with seven percent fill, four shells, and a layer height of 0.2mm.
Table 6 below shows the eight 3D printed parts. The parts were created in SolidWorks. Major changes
from the design phase included adding battery blockers to the servo bracket, this difference can be seen in
Figure 21. This change was made so the batteries would avoid hitting the DC bracket while the module is
moving. Another change was adding battery blockers to the insert wall to prevent the batteries from
sliding out of the module, this change can be seen in Figure 22. Some changes to the main casing
included the addition of a wider slot in the back of the module for the protoboard as well as the removal
of the battery brackets since they were moved to the insert wall, these changes gave more room inside the
module. These changes can be seen in Figure 23. The two halves of the DC holding bracket can be seen
in Figure 24, the servo to DC connector can be seen in Figure 25, and the wheel and wheel insert can be
seen in Figure 26.
Table 6: The parts that were 3D printed.
3D Printed Parts
Casing 4-sided
Casing Wall Insert
Casing Wheel
Wheel Insert
Servo to DC Connector
Servo Bracket
DC Holding Bracket (Left)
DC Holding Bracket (Right)
Figure 21: The original design to the servo bracket (left).The improved servo bracket with the battery
blockers (right).
32
Figure 22: The original design to the insert wall (left). The improved insert wall with the battery blockers
(right).
Figure 23: The original design to the module case (left). The improved module case without the battery
blockers and additional slot in the back (right).
33
Figure 24: The two halves of the DC bracket.
Figure 25: The connecting piece between the servo motor and DC brackets.
Figure 26: The wheel (left) and wheel insert (right) which are connected to the DC motor for rotation.
34
3.1.2 Module Protoboard:
The module circuit boards were created using a cut piece of protoboard. These boards were measured and
cut to be small enough to fit inside the casing but large enough to remain stationary when the module was
moving. A circuit diagram of the module board can be seen in Figure 27 and a detailed view of the actual
boards can be seen in Figure 28. The protoboard housed all necessary IC’s and chips in order to run the
modules. This includes the microcontroller, transceiver, DC driver, an adjustable voltage regulator, and
several connections for batteries and the two motors. In order to tie all of these components together,
hand-done wire wrapping was utilized. This provided a simple and efficient way to create, test, and make
changes to the boards as seen fit. A view of the back side of the board showing the wire wrapping can be
seen in Figure 29.
Figure 27: Multisim schematic for the module boards.
35
Figure 28: Detailed view of the module boards.
Figure 29: View of the back side of the module boards showing the wire wrapped connections.
The microcontroller utilized inside the modules was an Arduino Pro Mini. This ATMega328 board
contained all necessary pins to drive the wireless communications, the servo data lines, as well as the
PWM signals needed for the DC driver to run the DC motor. It also had the necessary unregulated voltage
input needed for direct integration with the chosen 7.4V batteries. This board is the brain of each module,
decoding and communicating needed signals to all necessary components for movement.
36
On the wireless communication side, the nRF2401 transceiver was utilized. This transceiver provided
great range with communication as well as integrated CRC or Cyclic Redundancy Check encoding for
error detection. The nRF2401 was also used because of the wealth of communication examples, tutorials,
available libraries, and ease of integration with the desired and ultimately used protocol. One trouble that
did occur with the board came when attempting to solder to the attached header pins. When trying to
solder wires to the pins, the transceiver would malfunction and halt communication with the controller.
Once discovered this was easily fixed by the sole use of wire wrapping.
Another important component on the module board is the DC driver. This small board allowed the
Arduino, and thus the controller, precise and adaptable control over the DC motor. Utilizing a PWM
signal from the Arduino, the board was able to change and control the speed of the motor. It also allowed
for easy direction changes with the addition of two digital signals from the Arduino.
All of these components, along with a voltage regulator and various connections to the motors and
batteries, are located on this single board that fits inside the module. These electronics are housed and
utilized within each of the modules and only need communication from the controller in order to make a
working and moving robot.
3.1.3 Controller Protoboard:
Protoboard and wire wrapping were again used when creating the controller. A schematic of the controller
board can be seen in Figure 30. Additional views of the controller’s front and back showing the
electronics as well as the wire wrapping done to connect and secure each component can be seen in
Figures 31-32. This controller used some similar components seen in the module boards, such as the
transceiver and an Arduino microcontroller. The controller board does contain some different components
including two joysticks, an ON/OFF toggle switch, and three LED’s. As a whole, this controller board
allowed for easy programming to fit the needs of different configurations as well as an easy and efficient
way to control the modules.
37
Figure 30: Multisim schematic for the controller board.
Figure 31: Front view of the controller board.
38
Figure 32: View of the back side of the controller board showing the wire wrapped connections.
A different Arduino was chosen for the controller. This time an Arduino Micro was utilized because it
allowed for more inputs and outputs needed for the joysticks, transceiver, and LED’s. It also ran at a
higher frequency, 16 MHz, which allowed for prompt outputted wireless commands to the modules.
The same transceiver (nRF2401) that was used in the modules was implemented in the controller. This
transceiver was definitely the work-horse of the bunch, sending out the command packets to all of the
modules that would then receive and decode their specific instructions.
The joysticks and their attached breakout boards are the main interaction between the program running
the controller and modules and the human controlling them. Using the two potentiometers for each axis,
the controller was set up to have the servo motor associated with left and right movement and the DC
controlled by up and down movement. This allowed for different servo angles depending on slight
variations of the joystick as well as quick DC speed and direction changes. Also, a built in button allowed
for an even more adaptive use of the controller. Using the button, the human controller is able to switch
between different modes on the fly. The utilized modes were a single module control mode, a
configuration control mode, and a servo calibration mode. Indications lights, the LED’s, were added in
order for the human controller to know the mode that the controller was in as well as which configuration
or module was being controlled at a certain time. A detailing of the different controller modes and their
associated LED indication can be seen in Table 7.
39
Table 7: The LED outputs on the controller and the associated modes.
3.1.4 Assembling Process:
In order to assemble the modules, the following steps must be completed:
1. First, slide the servo motor into the servo bracket, making sure to have the wires going toward the
notched end of the bracket (Figure 33 - top left).
2. Next, with the DC motor shaft hub and 3D printed wheel securely connected to the DC motor,
attach the DC motor brackets (Figure 33 - top right). This requires the printed servo to DC
connector piece to be securely on the DC bracket peg (Figure 33 - bottom). Make sure to solder
the DC magnetic encoder directly onto the DC motor before attaching the brackets.
3. With the motors prepared, slide the metal rod through the servo bracket hole and mount the DC
motor to the servo (Figure 34). Make sure to connect the servo to DC connector to the second
hole of the servo arm.
40
Figure 33: Servo motor and bracket (Top-Left). DC motor and bracket (Top-Right). Servo to DC
connector (Bottom).
Figure 34: Completely assembled motor housing with servo motor and DC motor connected brackets.
4. With the motors completely assembled together, plug the servo motor into the 3-pin servo
connection on the module board. The ground for the servo is located closest to the Arduino.
Attach the DC wires from the encoder on the DC motor to the pins on the module board. Make
sure to make the correct connections (M1 and M2 are the pins closest to the DC driver).
41
5. At this point, carefully connect the batteries to the module board. Double check before plugging
the batteries in that the RED wire is facing toward the inside of the module board. Figure 35
shows the made connections between the board and the batteries, servo, and DC/encoder.
Figure 35: Correctly connected DC, servo, and batteries. Note the direction of the battery wires and the
servo connector.
6. Next, carefully take the connected board and components and gently put them into the main
module casing. Have all the components sit securely but have them loose enough for the servo
motor to move freely. The batteries may become unconnected at this point which requires the
removal of the board and all components so they can be again correctly connected.
7. Finally, carefully put the wall insert into the channel and guide it to the seated position paying
close attention to the wires and their positions in the module. At this point the module is complete
with all components secure and unmoving except for the servo which should be free to cover all
of its angles. Figure 36 shows all of the components inside the module without the wall insert
(left) and the completed and fully assembled module (right).
42
Figure 36: Module with all electronics carefully placed inside (Left) and the complete and fully
assembled module (Right).
3.1.5 Software Development:
There were two sets of code used during this project, the code for the Arduinos inside the modules and
code for the controller. All the modules used nearly identical code, the one difference is a ModID
variable which represents the identification number of the module. The number is used to designate
which section of the wireless packet the module will grab the commands from. After the module code
looks through the received data and determines which commands to execute it sends the needed signals to
the DC and servo motor. There is also a section of the code to calibrate the servo motor, which changes
the base angle that the servo is set to. This is to allow for adjustments if the servo connection to the DC
bracket is misaligned. The module code can be seen in Appendix B and an overview of the module code
process can be seen in Figure 37.
43
Figure 37: Flowchart detailing the module code.
The controller code is used to take the signals from the two joysticks and transmits the corresponding
commands to the modules. To make sending commands easier in the code the function toModule was
created, which takes the parameters: the module ID, servo angle, servo calibration, DC direction, and DC
speed. It then puts these values in the correct section of the RFTxBuffer to transmit out to the modules.
The controller has different states that it represents using the LEDs on the controller. The red LED
represents the overall mode, while the two yellow LEDs represent the different sections of the mode.
Initially the red LED is off, which represents single module control, where each joystick can control a
single module. In this case the yellow LEDs represent which modules are being controlled, which could
be 0 and 1, 2 and 3, etc. Since there are not modules for all the available the fourth state is currently set to
control 1 and 2 to allow for more options during the testing phase. The next mode is to control
configurations, this mode is represented with the red LED being dimly lit. In this case the yellow LEDs
represent the wheeled, caterpillar, and buffer configurations, which are states 0-2, respectively. The
wheeled state sets the servos to a fixed angle on modules 0-3 so the wheels are touching the ground. The
left joystick is then responsible for the DC motors of 0 and 1, while the right controls the DC of 2 and 3.
The caterpillar configuration uses the forwards and backwards of the right joystick to cause the servos to
move in a wavelike motion. This is done through the use of a while loop, when held forward the joystick
will start the wave motion at the front, and pointing in the backwards direction will cause the wave to start
at the back. By holding the left joysticks forward it will cause the modules to straighten out, moving the
servo to the default set position. Currently in order to turn the caterpillar motion the mode has to be
switched to the single module mode, which will allow for the lead modules DC motor to be turned to
44
rotate the wheel and change direction. The buffer configuration is much like the wheeled configuration,
but the servos are set at the default position so they can’t be turned when spinning the DC motors. The
code for the controller can be seen in Appendix C as well as the flowchart in Figure 38.
Figure 38: The flowchart of the controller software.
45
3.2 Prototype Cost Breakdown
Many components were purchased in order to complete this project. Table 8 shows the cost breakdown
for the completed modules. These were all of the components used in the module boards, casing, and
controller. As shown the total cost of the completed project was $753.92. Taking away the components
used solely for the controller gives the total module cost $720.97 driving the cost per module (given that
enough materials were present to make 6 modules) to $120.16. This was a very important aspect in the
design. For the project as a whole to be low-cost, the cost of the modules had to be as cheap as possible.
Table 8: Cost breakdown for the completed Module Robot project.
It is also important to note the comparison between the 1st semester project estimate and cost per module
also noted in Table 8. The 1st semester budgeting predicted a total project cost of $671.71. Although
seemingly more, this semester’s total cost includes enough materials to make 1 more additional module
compared to the first semester’s five. Also, taking out some of the components such as the magnets, the
metal plates, the current sensors and associated resistors, and other various PCB components lowered the
46
price of the cost per module about $14.00. Table 9 details the components that were purchased but were
not utilized in the final design. Although accounting for $82.84 of our budget, these components could be
utilized in a later project to incorporate a PCB design for the modules. This gives us a total amount spent
of $836.76.
Table 9: Cost breakdown of purchased but unused components.
47
Section IV: Testing
48
4.1 Testing Requirements and Methods
4.1.1 Three Types of Motion:
The first requirement that the modules had to complete is three different types of motion from different
configurations. The group came up with three types of configurations that use different forms of motion.
The first type is a wheeled configuration. This type has the wheel end of the module facing outward,
where the servo is then able to point the wheels downward to lift the modules up. By rotating the wheel
with the DC motor it is possible to move the modules forward, backwards, and turn based on the speed
difference of the wheels. This configuration is the fastest configuration, which has the ability to travel
over slight elevation changes and many different types of surfaces. This type of configuration can be seen
with two modules in Figure 39, and four modules in Figure 40.
Figure 39: The wheeled configuration using two modules.
Figure 40: The wheeled configuration using four modules.
The second configuration created was a buffer type motion. This was implemented by having the wheel
end of the module pointing down toward the floor. As the wheel spins it can allow the module to rotate
around a non-spinning module or in a specific direction depending on which modules are spinning. This
configuration allows it to move in almost any two dimensional direction, but cannot travel over different
elevations or on a loose surface. This this type of configuration can be seen with two modules in Figure
41, and four modules in Figure 42.
Figure 41: The buffer configuration using two modules.
49
Figure 42: The buffer configuration using four modules.
The final configuration that was created was a caterpillar like motion. In this configuration the modules
are assembled in a line with the wheeled face pointing forward for all modules. This configuration
oscillates the servos in a wavelike pattern from front to back or back to front lifting the modules in a
caterpillar like movement. The front module can be used to turn the configuration by pointing the wheel
to the ground and using the DC motor to turn the wheel. This is the slowest configuration, the wavelike
motion pushes the modules forward toward the wheel end, can lift itself over a greater elevations than the
others, and can turn using the leading module. This this type of configuration can be seen with two
modules in Figure 43, and four modules in Figure 44.
Figure 43: The caterpillar configuration using two modules.
Figure 44: The caterpillar configuration using four modules.
4.1.2 Movement Accuracy:
In order to prove that the modules could be moved accurately using the controller a course was set up
with a ten foot distance to a square foot goal. This test was used to show that each configuration could
move successfully and in an accurate manner. Each configuration proved that it could be navigated into
the goal, which satisfied our requirement.
50
4.1.3 Battery Lifespan:
From the first semester calculations it was predicted that at maximum load of the servo and DC motor the
batteries would last roughly 36 minutes. To ensure that the modules could be used for a significant time
without needing recharged a goal of at least 20 minutes was set. No load conditions were first checked by
allowing the servo to be set at an angle and the DC motor to run continuously. This test was stopped after
4 hours and 30 minutes, the DC motor was still spinning but was beginning to overheat. While other
testing was in progress the modules were subjected to varying amounts of load and it is estimated that the
batteries will last at least 2 hours without major effects to the performance of the motors. Based on these
tests it was concluded that the modules would last much longer than our 20 minute goal of normal usage.
4.1.4 Prototype Weight:
In the first semester it was estimated that the maximum weight our modules could be is 400 grams. This
is based on the torque of the servo and DC motors, our goal was to be under this 400 grams. From the
initial parts it was estimated that our modules would be around 330 grams. After construction the weight
of the modules was found to be 275 grams. This difference was due to the replacement of many of the
metal parts with light weight alternative, as well as changes to the casing design that required less plastic
and a lower fill rate. Based on this found weight the modules meet our requirements for this test.
4.1.5 Wireless Communications Distance:
The final test that was performed was a communications distance test. A distance of at least 30 feet in
open air was set for this goal. This is to ensure that the user has full control of the module when using the
controller from a reasonable distance of view. When tested in open air conditions the module was able to
receive commands sent from the controller at a distance of roughly 50 feet, which meets our predefined
goal.
51
Section V: Conclusions and Recommendations
52
5.1 Conclusions
These prototypes meet the design goals and specifications set forth at the beginning of this project. Each
module has an Arduino which allows them to be reprogrammable for future designs or additional sensors
to be implemented. All modules have two batteries, so the power is non-restricting and rechargeable.
The group spent $836.76, which is less than the budget of $1000. The group was able to assemble three
different configurations, comprising of at least 2 modules, each utilizing a different form of motion.
Because a controller was implemented such that a user could dynamically alter the movement of a
configuration, the requirement for two types of spatial awareness was deemed inapplicable to the design.
It is considered that the user of the controller acts as the sensors rather than the module utilizing sensors
of its own. The modules do still have an encoder connected to the DC motor to measure how the fast the
DC motor is spinning, but it is not currently utilized by the module software.
The prototypes also meet all the testing requirements that were set. Each configuration was able to
perform a unique type of motion and be accurately controlled at a reasonable distance. The batteries
proved to supply enough power to keep the modules running for over an hour of use. The modules are
also within the weight goals to ensure the motors are able to move correctly.
Overall, the group is proud to know that the IPFW department of engineering is fully satisfied with the
prototypes built, and are considering using them for future projects and continuing to
make advancements to the design.
The team would like to thank our advisor, Dr. Liu, for helping us through each stage of the design and
implementation process.
5.2 Recommendations
One way in which the design could be improved by adding an On/Off switch to the modules. Currently
the batteries must be removed to turn the modules off which requires the modules to be disassembled.
Adding a switch would simplify the process and allow the modules to stay assembled and be reset with
much more ease.
Another improvement could be the switch from the protoboard to a PCB. This would help reduce the
space it takes up as well as allow for a more streamlined production of boards and modules. The group
initially worked toward a PCB, was running low on time, and had issues such as the transceiver not
functioning after being soldered on the board. This was due to the solderer overheating the transceiver.
A third improvement to the board would be a fuse or diode for circuit protection. As of right now if either
battery is plugged in backwards it would fry the Arduino, making it unusable.
Currently the encoder is not utilized by the module code, but pins are wired to from the microcontroller to
the encoder output pins of the protoboard. By adding the encoder and modifying the code to react to
encoder values, it would be possible to reduce the difference between how fast each DC motor spins.
This would allow for better control of the modules.
53
One weak point in the current design is the connection between the DC bracket and servo bracket, which
uses a small 3D printed connection. This piece is prone to breaking when the there is a significant load
that the servo is attempting to lift. By replacing this piece with a stronger material, such as metal or
redesigning the connection completely, this will greatly improve the overall strength of the design.
The final recommendation would be to use a 3D printer with a better resolution. This would allow for
parts to be more identical and reduce the amount of work needed to get the parts to fit together.
54
Appendix A
Four Sided Module Casing
Servo Bracket
55
Appendix A (cont.)
DC Bracket
56
Appendix A (cont.)
Casing Wall Insert
Casing Plastic Insert
57
Appendix A (cont.)
Wheel
Wheel Plastic Insert
58
Appendix B: Source Code for Module
//---------------------------------------------------------------------------------------
//Filename: src_module.ino
//Project: Low-Cost Reconfigurable Modular Robots
//Code: Master Transmitter
//By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groff
//Course: ECE 406 - Senior Design II
//Created: January - April, 2015
//---------------------------------------------------------------------------------------
#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
#include <Arduino.h>
//MODULE ID
int ModID = 3;
uint8_t dcDirection;
uint8_t encoderSpeed;
//
// transceiver hardware configuration: ATMega
//
#define CE 9
#define CS 10
#define ROLE 7
#define BAUD 57600
RF24 radio(CE, CS);
//
// Topology
//
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
//Initalize transceiver buffers
#define BUFFERLENGTH 24
uint8_t RFTxBuffer[BUFFERLENGTH];
uint8_t RFRxBuffer[BUFFERLENGTH];
//DC Motor Information
int PWMA = 6; //Speed control
int AIN1 = 4; //Direction
int AIN2 = 5; //Direction
59
//Encoder Information
int encoder0PinA = 7;
int encoder0PinB = 8;
int encoder0Pos = 0;
int encoder0PinALast;
int encoder1PinALast;
int encoderPin0;
int encoderPin1;
int MSpeed;
int tics4rev = 600;
//Servo Motor Information
int servo = 3;
int servoMid = 96;
int servoMax = 102;
int servoMin = 90;
int updateCheck = 0;
uint8_t prevServoAngle = 97;
uint8_t servoAngle = 97;
uint8_t servoSet = 0;
void clearBuffer(uint8_t *buf) {
for (int i = 0; i < BUFFERLENGTH; i++) {
buf[i] = 0x00;
}
}
void clearBuffer(uint8_t *buf, int startByte) {
int i = startByte;
for (i; i < BUFFERLENGTH; i++) {
buf[i] = 0x00;
}
}
void sendTxBuf()
{
radio.stopListening();
radio.write( &RFTxBuffer, sizeof(RFTxBuffer) );
// Now, continue listening
radio.startListening();
}
int serial_putc( char c, FILE * )
{
Serial.write( c );
return c;
60
}
void printf_begin(void)
{
fdevopen( &serial_putc, 0 );
}
void setup(void)
{
//
// Print preamble
//
Serial.begin(BAUD);
printf_begin();
printf("Modular Robot Projectnr");
printf("Module Adress: %dnr", ModID);
//
// Setup and configure rf radio
//
clearBuffer(RFTxBuffer);
clearBuffer(RFTxBuffer);
radio.begin();
// optionally, reduce the payload size. seems to
// improve reliability
radio.setPayloadSize(BUFFERLENGTH);
//
// Open pipes to other nodes for communication
//
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1, pipes[0]);
radio.powerUp() ;
radio.startListening();
//radio.enableDynamicPayloads();
//
// Dump the configuration of the rf unit for debugging
//
radio.printDetails();
//Establish DC Motor Information and Encoder Values
//pinMode(STBY, OUTPUT);
61
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode (encoder0PinA, INPUT);
pinMode (encoder0PinB, INPUT);
encoder0PinALast = digitalRead(encoder0PinA);
encoder1PinALast = digitalRead(encoder0PinB);
pinMode(servo, OUTPUT);
}
void loop(void)
{
///////////////////////////////////////////Transceiver///////////////////////////////////
int i = 0;
if (Serial.available() > 0) {
printf("Sending: ");
while ((Serial.available() > 0) && (i < BUFFERLENGTH)) {
// read the incoming byte:
RFTxBuffer[i] = Serial.read();
printf("%02x ", RFTxBuffer[i]);
i++;
// say what you got:
if (Serial.available() <= 0) {
sendTxBuf();
clearBuffer(RFTxBuffer);
printf("n");
}
}
}
if ( radio.available() )
{
// Dump the payloads until we've gotten everything
// bool done = false;
printf("Received: ");
//while (!done)
//{
// Fetch the payload, and see if this was the last one.
//done = radio.read( &RFRxBuffer, BUFFERLENGTH );
//}
radio.read( &RFRxBuffer, sizeof(RFRxBuffer) );
for (int j = 0; j < sizeof(RFRxBuffer); j++)
{
printf("%02x ", RFRxBuffer[j]);
}
/////////////////////////////////////////////^TRANSCEIVER^///////////////////////////////
62
servoAngle = RFRxBuffer[(ModID + 1) * 2];
servoAngle = servoAngle >> 3;
servoSet = RFRxBuffer[(ModID + 1) * 2];
servoSet = servoSet >> 1;
servoSet = (servoSet & '00000001');
servoAngle = servoAngle + servoMin;
if ( (servoAngle >= servoMin) & (servoAngle <= servoMax)) {
if (servoAngle > prevServoAngle) {
while (servoAngle > prevServoAngle) {
prevServoAngle = prevServoAngle + 1;
analogWrite(servo, prevServoAngle);
delay(25);
}
}
else {
while (servoAngle < prevServoAngle) {
prevServoAngle = prevServoAngle - 1;
analogWrite(servo, prevServoAngle);
delay(25);
}
}
}
if (updateCheck == 0) {
if (servoSet == 1) {
servoMid = servoAngle;
servoMax = servoAngle + 6;
servoMin = servoAngle - 6;
updateCheck = 1;
}
}
if (servoSet == 0) {
updateCheck = 0;
}
dcDirection = RFRxBuffer[(ModID + 1) * 2];
dcDirection = dcDirection & 0x01;
encoderSpeed = RFRxBuffer[((ModID + 1) * 2) + 1];
move (1, encoderSpeed, dcDirection);
clearBuffer(RFRxBuffer);
printf("n");
}
}
void move(int motor, int speed, int direction) {
//Move specific motor at speed and direction
//motor:1 for A
//speed: 0 is off, and 255 is full speed
//direction: 0 clockwise, 1 counter-clockwise
63
//digitalWrite(STBY, HIGH); //disable standby
boolean inPin1 = LOW;
boolean inPin2 = HIGH;
if (direction == 1) {
inPin1 = HIGH;
inPin2 = LOW;
}
if (motor == 1) {
digitalWrite(AIN1, inPin1);
digitalWrite(AIN2, inPin2);
analogWrite(PWMA, speed);
}
}
void stop() {
//enable standby
//digitalWrite(STBY, LOW);
}
64
Appendix C: Source Code for Controller
//---------------------------------------------------------------------------------------
//Filename: src_controller.ino
//Project: Low-Cost Reconfigurable Modular Robots
//Code: Master Transmitter
//By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groff
//Course: ECE 406 - Senior Design II
//Created: January - April, 2015
//
//This code was developed to implement the master transmitter to control
//a modular robot. The master transmitter uses a SparkFun 5V, 16MHz embedded system
//along with an nRF24L01+ transceiver. Commands are sent via the transmitter
//and decoded by each module. Each module runs an instance of the src_module.ino
//program. The src_module.ino program handles the decoding and execution of the payloads
//created by this program and transmitted by the transceiver.
//
//Arduino Pin Connections
//
//A0 - Right Stick Horizontal
//A1 - Right Stick Vertical
//A2 - Left Stick Horizontal
//A3 - Left Stick Vertical
//D2 -
//D3 - Left State Light
//D4 -
//D5 - Right Stick Z
//D6 - Left Stick Z
//D7 - Right State Light 0
//D8 - Right State Light 1
//D9 -
//D10 -
//D11 -
//D12 -
//---------------------------------------------------------------------------------------
//Include files
#include <SPI.h>
#include <RF24.h>
#include <Arduino.h>
//Debug options
#define TX_DEBUG; //Transceiver TX/RX data
#define JST_DEBUG; //Joystick data
//Transceiver hardware configuration and instantiation
65
#define CE 9
#define CS 10
#define BAUD 57600
RF24 radio(CE, CS);
// Radio pipe addresses for master/module communication
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
//Initalize transceiver buffers
#define BUFFERLENGTH 24
uint8_t RFTxBuffer[BUFFERLENGTH]; //Buffer used for transmissions
uint8_t RFRxBuffer[BUFFERLENGTH]; //Buffer to store received data
//Initialize controller states = [Left stick, Right stick]
// Left 0 = Preprogrammed controlled configuration
// Left 1 = Controller controlled configuration
// Left 2 = Individual module control
// Right 0 = Preprogrammed configuration selection
// Right 1 = Controller configuration selection
// Right 2 = Module*2 (left stick) and Module*2+1 (right stick) selection
int controllerState[2] = {0, 0};
//Initialize controller configuration
const int leftStateLight = 3;
const int joyRightZ = 5;
const int joyLeftZ = 6;
const int rightStateLight0 = 7;
const int rightStateLight1 = 8;
//Array storing joystick information. Pinout: [LV, LH, LZ, RV, RH, RZ] = [A0, A1, D5, A2, A3, D6]
//Note: Voltages for right stick run 0-5V bottom to top, left to right.
//Note: Voltages for left stick run 5-0V bottom to top, left to right.
int joyState[6] = {512, 512, 1, 512, 512, 1};
//Used to keep track of the waves going through the snake/catepillar.
int wave = 0;
//Sets the servo angle if needs to be changed
int set = 0;
void clearBuffer(uint8_t *buf, int n) {
for (; n < BUFFERLENGTH; n++) {
buf[n] = 0x00;
}
}
void sendTxBuf()
{
//Increase Message ID
66
RFTxBuffer[1] = RFTxBuffer[1] + 1;
radio.stopListening();
#ifdef TX_DEBUG
printf("Sending: ");
for (int i = 0; i < BUFFERLENGTH; i++) {
printf("%02x ", RFTxBuffer[i]);
}
printf("n");
#endif
radio.write( &RFTxBuffer, sizeof(RFTxBuffer) );
delay(1);
radio.write( &RFTxBuffer, sizeof(RFTxBuffer) );
delay(1);
radio.write( &RFTxBuffer, sizeof(RFTxBuffer) );
// Now, continue listening
radio.startListening();
}
int serial_putc( char c, FILE * )
{
Serial.write( c );
return c;
}
void printf_begin(void)
{
fdevopen( &serial_putc, 0 );
}
void toModule(int address, int servoAngle, int servoSpeed, int dcDir, int dcSpeed)
{
RFTxBuffer[(address + 1) * 2] = servoAngle << 3 | servoSpeed << 1 | dcDir;
RFTxBuffer[(address + 1) * 2 + 1] = dcSpeed*3/4;
}
void setControllerLights()
{
//Right state lights show which individual module to control
switch (controllerState[1]) {
case 0:
digitalWrite(rightStateLight0, LOW);
digitalWrite(rightStateLight1, LOW);
break;
case 1:
digitalWrite(rightStateLight0, HIGH);
67
digitalWrite(rightStateLight1, LOW);
break;
case 2:
digitalWrite(rightStateLight0, LOW);
digitalWrite(rightStateLight1, HIGH);
break;
case 3:
digitalWrite(rightStateLight0, HIGH);
digitalWrite(rightStateLight1, HIGH);
break;
default:
controllerState[1] = 0;
setControllerLights();
break;
}
//Left state is main showing Automatic, Manual (Configuration), and single module control
switch (controllerState[0]) {
case 0:
analogWrite(leftStateLight, 0); //Single Module
break;
case 1:
analogWrite(leftStateLight, 50); //Manual
break;
case 2:
analogWrite(leftStateLight, 255); //Automatic
break;
default:
controllerState[0] = 0;
setControllerLights();
break;
}
}
void getJoyStates() {
joyState[0] = analogRead(A0);
joyState[1] = analogRead(A1);
joyState[2] = digitalRead(joyRightZ);
joyState[3] = analogRead(A2);
joyState[4] = analogRead(A3);
joyState[5] = digitalRead(joyLeftZ);
#ifdef JST_DEBUG
printf("Joystick States: ");
for (int i = 0; i < 6; i++) {
printf("%d ", joyState[i]);
}
printf("n");
#endif
68
//debounce switches
if (joyState[2] == 0 || joyState[5] == 0) {
if (joyState[2] == 0) {
controllerState[0] = (controllerState[0] + 1) % 3;
} else {
controllerState[1] = (controllerState[1] + 1) % 4;
}
setControllerLights();
while (joyState[2] == 0 || joyState[5] == 0) {
joyState[2] = digitalRead(joyRightZ);
joyState[5] = digitalRead(joyLeftZ);
}
delay(50);
}
}
void setup(void)
{
//
// Print preamble
//
Serial.begin(BAUD);
printf_begin();
printf("Project: Low-Cost Reconfigurable Modular Robotsn");
printf("Code: Master Transmittern");
printf("Filename: src_master.inon");
printf("By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groffnn");
//
// Setup and configure rf radio
//
clearBuffer(RFTxBuffer, 0);
clearBuffer(RFRxBuffer, 0);
pinMode(leftStateLight, OUTPUT);
pinMode(joyRightZ, INPUT);
digitalWrite(joyRightZ, HIGH);
pinMode(joyLeftZ, INPUT);
digitalWrite(joyLeftZ, HIGH);
pinMode(rightStateLight0, OUTPUT);
pinMode(rightStateLight1, OUTPUT);
radio.begin();
// optionally, reduce the payload size. seems to
// improve reliability
radio.setPayloadSize(BUFFERLENGTH);
69
//
// Open pipes to other nodes for communication
//
// Open 'our' pipe for writing
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1, pipes[1]);
radio.powerUp() ;
radio.startListening();
// Dump the configuration of the rf unit for debugging
radio.printDetails();
for (int i = 0; i < 11; i++) {
toModule(i, 512 * 13 / 1023, 0, 0, 0);
}
setControllerLights();
}
void loop(void)
{
printf("state[0] = %d n state[1] = %dn", controllerState[0], controllerState[1] );
//clearBuffer(RFTxBuffer, 2);
getJoyStates();
//For Single Module Control
if (controllerState[0] == 0) {
if (joyState[0] > 600) {
toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 1, joyState[0] / 4);
}
if (joyState[0] < 400) {
toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
}
if (joyState[0] < 600 && joyState[0] > 400) {
toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 0, 0);
}
if (joyState[3] < 400) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(controllerState[1] * 2 + 1, 6, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[4] > 600) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[4] < 400) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
}
70
if (joyState[3] > 600) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(controllerState[1] * 2 + 1, 6, 0, 0, joyState[3] / 4);
}
if (joyState[4] > 600) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4);
}
if (joyState[4] < 400) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4);
}
}
if (joyState[3] < 600 && joyState[3] > 400) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(controllerState[1] * 2 + 1, 6, 0, 0, 0);
}
if (joyState[4] > 600) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, 0);
}
if (joyState[4] < 400) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, 0);
}
}
if (controllerState[1] == 3) {
if (joyState[0] > 600) {
toModule(1, joyState[1] * 13 / 1023, 0, 1, joyState[0] / 4);
}
if (joyState[0] < 400) {
toModule(1, joyState[1] * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
}
if (joyState[0] < 600 && joyState[0] > 400) {
toModule(1, joyState[1] * 13 / 1023, 0, 0, 0);
}
if (joyState[3] < 400) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(2, 6, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[4] > 600) {
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[4] < 400) {
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
}
if (joyState[3] > 600) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(2, 6, 0, 0, joyState[3] / 4);
}
if (joyState[4] > 600) {
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4);
}
if (joyState[4] < 400) {
71
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4);
}
}
if (joyState[3] < 600 && joyState[3] > 400) {
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(2, 6, 0, 0, 0);
}
if (joyState[4] > 600) {
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, 0);
}
if (joyState[4] < 400) {
toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, 0);
}
}
}
}
//For Manual control of module configurations
if (controllerState[0] == 1) {
if (controllerState[1] == 0) { //Car 0,1 are left wheels, 2,3 are right wheels
if (joyState[0] > 600) {
toModule(0, 1000 * 13 / 1023, 0, 1, joyState[0] / 4);
toModule(1, 1000 * 13 / 1023, 0, 1, joyState[0] / 4);
}
if (joyState[0] < 400) {
toModule(0, 1000 * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
toModule(1, 1000 * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
}
if (joyState[0] < 600 && joyState[0] > 400) {
toModule(0, 1000 * 13 / 1023, 0, 0, 0);
toModule(1, 1000 * 13 / 1023, 0, 0, 0);
}
if (joyState[3] > 600) {
toModule(2, 1000 * 13 / 1023, 0, 0, joyState[3] / 4);
toModule(3, 1000 * 13 / 1023, 0, 0, joyState[3] / 4);
}
if (joyState[3] < 400) {
toModule(2, 1000 * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
toModule(3, 1000 * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[3] < 600 && joyState[3] > 400) {
toModule(2, 1000 * 13 / 1023, 0, 0, 0);
toModule(3, 1000 * 13 / 1023, 0, 0, 0);
}
}
if (controllerState[1] == 1) { //Snake/Oscillation motion
if (joyState[0] > 600) {
toModule(0, 512 * 13 / 1023, 0, 0, 0);
toModule(1, 512 * 13 / 1023, 0, 0, 0);
72
toModule(2, 512 * 13 / 1023, 0, 0, 0);
toModule(3, 512 * 13 / 1023, 0, 0, 0);
toModule(4, 512 * 13 / 1023, 0, 0, 0);
}
if (joyState[3] < 400) {
toModule(0, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
toModule(0, 512 * 13 / 1023, 0, 0, 0);
toModule(1, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
toModule(0, 50 * 13 / 1023, 0, 0, 0);
toModule(1, 512 * 13 / 1023, 0, 0, 0);
toModule(2, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
while (joyState[3] < 400) {
toModule(wave % 5, 512 * 13 / 1023, 0, 0, 0);
toModule((wave + 1) % 5, 50 * 13 / 1023, 0, 0, 0);
toModule((wave + 2) % 5, 512 * 13 / 1023, 0, 0, 0);
toModule((wave + 3) % 5, 1000 * 13 / 1023, 0, 0, 0);
toModule((wave + 4) % 5, 512 * 13 / 1023, 0, 0, 0);
wave++;
getJoyStates();
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
}
}
if (joyState[3] > 600) {
toModule(4, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
toModule(4, 512 * 13 / 1023, 0, 0, 0);
toModule(3, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
toModule(4, 50 * 13 / 1023, 0, 0, 0);
toModule(3, 512 * 13 / 1023, 0, 0, 0);
73
toModule(2, 1000 * 13 / 1023, 0, 0, 0);
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
while (joyState[3] > 600) {
toModule((wave + 4) % 5, 512 * 13 / 1023, 0, 0, 0);
toModule((wave + 3) % 5, 50 * 13 / 1023, 0, 0, 0);
toModule((wave + 2) % 5, 512 * 13 / 1023, 0, 0, 0);
toModule((wave + 1) % 5, 1000 * 13 / 1023, 0, 0, 0);
toModule((wave + 0) % 5, 512 * 13 / 1023, 0, 0, 0);
wave++;
getJoyStates();
sendTxBuf();
sendTxBuf();
sendTxBuf();
delay(100);
}
}
wave = 0;
}
if (controllerState[1] == 2) { //4 modules walking
if (joyState[0] > 600) {
toModule(0, 512 * 13 / 1023, 0, 1, joyState[0] / 4);
toModule(1, 512 * 13 / 1023, 0, 1, joyState[0] / 4);
}
if (joyState[0] < 400) {
toModule(0, 512 * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
toModule(1, 512 * 13 / 1023, 0, 0, 255 - joyState[0] / 4);
}
if (joyState[0] < 600 && joyState[0] > 400) {
toModule(0, 512 * 13 / 1023, 0, 0, 0);
toModule(1, 512 * 13 / 1023, 0, 0, 0);
}
if (joyState[3] > 600) {
toModule(2, 512 * 13 / 1023, 0, 0, joyState[3] / 4);
toModule(3, 512 * 13 / 1023, 0, 0, joyState[3] / 4);
}
if (joyState[3] < 400) {
toModule(2, 512 * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
toModule(3, 512 * 13 / 1023, 0, 1, 255 - joyState[3] / 4);
}
if (joyState[3] < 600 && joyState[3] > 400) {
toModule(2, 512 * 13 / 1023, 0, 0, 0);
toModule(3, 512 * 13 / 1023, 0, 0, 0);
}
}
}
//For Auto control of modules
74
if (controllerState[0] == 2) {
set = 0;
if (joyState[0] > 600 || joyState[0] < 400) {
set = 1;
}
if (joyState[1] < 600 && joyState[1] > 400) {
toModule(controllerState[1] * 2, 6, set, 0, 0);
}
if (joyState[1] > 600) {
toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, set, 0, 0);
}
if (joyState[1] < 400) {
toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, set, 0, 0);
}
set = 0;
if (joyState[3] > 600 || joyState[3] < 400) {
set = 1;
}
if (joyState[4] < 600 && joyState[4] > 400) {
toModule(controllerState[1] * 2 + 1, 6, set, 0, 0);
}
if (joyState[4] > 600) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, set, 0, 0);
}
if (joyState[4] < 400) {
toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, set, 0, 0);
}
set = 0;
}
sendTxBuf();
/*if ( radio.available() )
{
// Dump the payloads until we've gotten everything
bool done = false;
printf("Received: ");
while (!done)
{
// Fetch the payload, and see if this was the last one.
done = radio.read( &RFRxBuffer, BUFFERLENGTH );
}
for (int j = 0; j < BUFFERLENGTH; j++)
{
printf("%02x ", RFRxBuffer[j]);
}
clearBuffer(RFRxBuffer, 2);
printf("n");
75
}*/
}

More Related Content

Similar to Low-Cost Reconfigurable Modular Robot Design

Design and Simulation of Local Area Network Using Cisco Packet Tracer
Design and Simulation of Local Area Network Using Cisco Packet TracerDesign and Simulation of Local Area Network Using Cisco Packet Tracer
Design and Simulation of Local Area Network Using Cisco Packet TracerAbhi abhishek
 
Workflow management solutions: the ESA Euclid case study
Workflow management solutions: the ESA Euclid case studyWorkflow management solutions: the ESA Euclid case study
Workflow management solutions: the ESA Euclid case studyMarco Potok
 
Software Development Taxonomy
Software Development TaxonomySoftware Development Taxonomy
Software Development TaxonomyAli Gholami
 
Digital System Design with FPGAs Lab Manual.pdf
Digital System Design with FPGAs Lab Manual.pdfDigital System Design with FPGAs Lab Manual.pdf
Digital System Design with FPGAs Lab Manual.pdfAmairullahKhanLodhi1
 
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...Mohamed Marei
 
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...ijtsrd
 
The potential in Drupal 8.x and how to realize it
The potential in Drupal 8.x and how to realize itThe potential in Drupal 8.x and how to realize it
The potential in Drupal 8.x and how to realize itAngela Byron
 
India Energy Security Scenarios Calculator - BTech Project
India Energy Security Scenarios Calculator - BTech ProjectIndia Energy Security Scenarios Calculator - BTech Project
India Energy Security Scenarios Calculator - BTech ProjectAditya Gupta
 
Mobile Friendly Web Services - Thesis
Mobile Friendly Web Services - ThesisMobile Friendly Web Services - Thesis
Mobile Friendly Web Services - ThesisNiko Kumpu
 
Smart Mirror Summer Report
Smart Mirror Summer ReportSmart Mirror Summer Report
Smart Mirror Summer ReportJabari Barton
 
Flow of PCB Designing in the manufacturing process
Flow of PCB Designing in the manufacturing processFlow of PCB Designing in the manufacturing process
Flow of PCB Designing in the manufacturing processSharan kumar
 
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...Hironori Washizaki
 
Sample projectdocumentation
Sample projectdocumentationSample projectdocumentation
Sample projectdocumentationhlksd
 
Definition of the ARCADIA project context model
Definition of the ARCADIA project context modelDefinition of the ARCADIA project context model
Definition of the ARCADIA project context modelEU ARCADIA PROJECT
 
PrashantChoudhary-IDC-Internship-report
PrashantChoudhary-IDC-Internship-reportPrashantChoudhary-IDC-Internship-report
PrashantChoudhary-IDC-Internship-reportPrashant Choudhary
 

Similar to Low-Cost Reconfigurable Modular Robot Design (20)

U-1.pptx
U-1.pptxU-1.pptx
U-1.pptx
 
Design and Simulation of Local Area Network Using Cisco Packet Tracer
Design and Simulation of Local Area Network Using Cisco Packet TracerDesign and Simulation of Local Area Network Using Cisco Packet Tracer
Design and Simulation of Local Area Network Using Cisco Packet Tracer
 
Workflow management solutions: the ESA Euclid case study
Workflow management solutions: the ESA Euclid case studyWorkflow management solutions: the ESA Euclid case study
Workflow management solutions: the ESA Euclid case study
 
Software Development Taxonomy
Software Development TaxonomySoftware Development Taxonomy
Software Development Taxonomy
 
Digital System Design with FPGAs Lab Manual.pdf
Digital System Design with FPGAs Lab Manual.pdfDigital System Design with FPGAs Lab Manual.pdf
Digital System Design with FPGAs Lab Manual.pdf
 
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...
Mohamed Marei 120126864 Dissertation Design and Construction of Hardware Add-...
 
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...
22 Re-Engineering Traditional Learning Model with Outcome-Based Learning Curv...
 
The potential in Drupal 8.x and how to realize it
The potential in Drupal 8.x and how to realize itThe potential in Drupal 8.x and how to realize it
The potential in Drupal 8.x and how to realize it
 
India Energy Security Scenarios Calculator - BTech Project
India Energy Security Scenarios Calculator - BTech ProjectIndia Energy Security Scenarios Calculator - BTech Project
India Energy Security Scenarios Calculator - BTech Project
 
Mobile Friendly Web Services - Thesis
Mobile Friendly Web Services - ThesisMobile Friendly Web Services - Thesis
Mobile Friendly Web Services - Thesis
 
Smart Mirror Summer Report
Smart Mirror Summer ReportSmart Mirror Summer Report
Smart Mirror Summer Report
 
Sp090317
Sp090317Sp090317
Sp090317
 
Assignment 1
Assignment 1Assignment 1
Assignment 1
 
Flow of PCB Designing in the manufacturing process
Flow of PCB Designing in the manufacturing processFlow of PCB Designing in the manufacturing process
Flow of PCB Designing in the manufacturing process
 
Portfolio
PortfolioPortfolio
Portfolio
 
Zap Scanning
Zap ScanningZap Scanning
Zap Scanning
 
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...
SWEBOK Guide Evolution and Its Emerging Areas including Machine Learning Patt...
 
Sample projectdocumentation
Sample projectdocumentationSample projectdocumentation
Sample projectdocumentation
 
Definition of the ARCADIA project context model
Definition of the ARCADIA project context modelDefinition of the ARCADIA project context model
Definition of the ARCADIA project context model
 
PrashantChoudhary-IDC-Internship-report
PrashantChoudhary-IDC-Internship-reportPrashantChoudhary-IDC-Internship-report
PrashantChoudhary-IDC-Internship-report
 

Recently uploaded

Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...Call Girls in Nagpur High Profile
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...roncy bisnoi
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordAsst.prof M.Gokilavani
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdfKamal Acharya
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxupamatechverse
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxupamatechverse
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfKamal Acharya
 
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGSIVASHANKAR N
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Christo Ananth
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Call Girls in Nagpur High Profile
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...Call Girls in Nagpur High Profile
 

Recently uploaded (20)

Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete RecordCCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
CCS335 _ Neural Networks and Deep Learning Laboratory_Lab Complete Record
 
University management System project report..pdf
University management System project report..pdfUniversity management System project report..pdf
University management System project report..pdf
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Introduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptxIntroduction to IEEE STANDARDS and its different types.pptx
Introduction to IEEE STANDARDS and its different types.pptx
 
Introduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptxIntroduction and different types of Ethernet.pptx
Introduction and different types of Ethernet.pptx
 
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTINGMANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
MANUFACTURING PROCESS-II UNIT-1 THEORY OF METAL CUTTING
 
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANJALI) Dange Chowk Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...Top Rated  Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
Top Rated Pune Call Girls Budhwar Peth ⟟ 6297143586 ⟟ Call Me For Genuine Se...
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...Booking open Available Pune Call Girls Pargaon  6297143586 Call Hot Indian Gi...
Booking open Available Pune Call Girls Pargaon 6297143586 Call Hot Indian Gi...
 

Low-Cost Reconfigurable Modular Robot Design

  • 1. Indiana University - Purdue University Fort Wayne Department of Engineering ECE405 - ECE406 Capstone Senior Design Project Report #2 Project Title: Low-Cost Reconfigurable Modular Robots Team Members: Timothy Boles Christopher Coffee Justin Galvan Steven Groff Faculty Advisor: Yanfei Liu, Ph.D Date: May 4, 2015
  • 2. 2 Table of Contents Acknowledgements ........................................................................................................................4 Abstract.........................................................................................................................................5 Section I: Problem Statement.........................................................................................................6 1.1 Requirements and Specifications..............................................................................................7 1.2 Given Parameters ...................................................................................................................7 1.3 Design Variables: ...................................................................................................................7 1.3.1 Hardware:........................................................................................................................7 1.3.2 Software:.........................................................................................................................7 1.3.3 System Conditions: ..........................................................................................................8 1.4 Limitations and Constraints: ....................................................................................................8 1.5 Additional Considerations: ......................................................................................................8 Section II: Detailed Design.............................................................................................................9 2.1 Functional Overview of Module.............................................................................................10 2.1.1 Overall Overview...........................................................................................................10 2.1.2 Operating Process Overview ...........................................................................................10 2.2 Controller Board...................................................................................................................12 2.2.1 Microcontroller..............................................................................................................14 2.2.2 Current Sensor...............................................................................................................15 2.2.3 Voltage Regulators.........................................................................................................17 2.2.4 DC Motor Driver............................................................................................................18 2.2.5 Magnetic Encoder for DC Motor .....................................................................................19 2.3 Wireless Communication ......................................................................................................19 2.4 Motors and Battery...............................................................................................................20 2.4.1 Picking the Motors and Batteries .....................................................................................20 2.4.2 Power Calculations.........................................................................................................22 2.5 Casing.................................................................................................................................22 2.5.1 Casing Overview............................................................................................................22 2.5.2 3-D Printer Settings........................................................................................................26 2.6 Changes to the Initial Design: ................................................................................................27
  • 3. 3 2.7 Final Prototype Design..........................................................................................................29 Section III: Prototype Construction .............................................................................................30 3.1 Prototype Construction..........................................................................................................31 3.1.1 Casing and Brackets: ......................................................................................................31 3.1.2 Module Protoboard:........................................................................................................34 3.1.3 Controller Protoboard:....................................................................................................36 3.1.4 Assembling Process:.......................................................................................................39 3.1.5 Software Development: ..................................................................................................42 3.2 Prototype Cost Breakdown ....................................................................................................45 Section IV: Testing ......................................................................................................................47 4.1 Testing Requirements and Methods........................................................................................48 4.1.1 Three Types of Motion: ..................................................................................................48 4.1.2 Movement Accuracy: .....................................................................................................49 4.1.3 Battery Lifespan:............................................................................................................50 4.1.4 Prototype Weight: ..........................................................................................................50 4.1.5 Wireless Communications Distance: ................................................................................50 Section V: Conclusions and Recommendations.............................................................................51 5.1 Conclusions .........................................................................................................................52 5.2 Recommendations ................................................................................................................52 Appendix A..................................................................................................................................54 Appendix B: Source Code for Module..........................................................................................58 Appendix C: Source Code for Controller .....................................................................................64
  • 4. 4 Acknowledgements We would like to express our appreciation to our advisor Dr. Yanfei Liu for allowing us to participate in this project. Without her guidance and direction this project would not have been possible. We would also like to thank Dr. Carlos Pomalaza-Ráez and Bill Westrick whose knowledge has been invaluable during this project. With their on-hand experience they greatly added to the quality and feasibility of the project. A special thanks is also needed for Dr. Zhuming Bi and Alfonso Costas who have been extremely helpful and available for all questions regarding the mechanical engineering aspects of this project. The group would also like to thank Bob Tilbury for his help with the PCB design as well as operating the 3D printers to print our parts. Finally, we would like to thank the IPFW Engineering Department for sponsoring this project.
  • 5. 5 Abstract An emerging topic in science today is modular technology. Modular robots provide a wide range of uses in many different areas. Industrial robots assemble the things we use every day, and some mobility robots help navigate and explore rough terrain. Applying the modular aspect on the robot allows for even more flexibility in use. The focus of this project is to design a class of modular robotic systems that can achieve different forms of movement. This modular robotic system could be used in future robotics courses as a teaching tool for future engineers in an undergraduate or graduate program. These robots can come in different forms involving several small modules attached together to form a working and moving robot. This type of design requires not only a mechanical flow between modules but also a steady electronic communication that gives modules the information they need in order to move in the correct manner. The system will be measured by the ability to be reprogrammed, it should have its own power supply so movement is not restricted, this power supply must be rechargeable, the modules should be interchanged easily, and be able to move in a variety of ways. After developing a design for a modular robotics platform in the Fall 2014 semester, that design was attempted to be completed in the Spring 2015 semester. Although the design was subjected to several modifications, a functional low-cost reconfigurable modular robotics platform was developed and several design aspects were tested to verify success. Because the project passed all of the subjected tests, it was determined that the implemented design met the requirements and specifications of this project.
  • 7. 7 1.1 Requirements and Specifications The following requirements and specifications must be met for a successful project: ➢ Central Control Unit - Each module must have a central control unit, such as an Arduino, this unit must be re-programmable, this will allow for operational changes to be made to the modules. ➢ Power - The modules must be powered by a non-restricting and rechargeable power supply. This is to remove the need to be attached to an outlet. This will allow for a greater range of motions and makes the modules more self-contained. ➢ Sensors - The modules must have some type of spatial awareness, this is to prevent the modules from running into object and damaging themselves. 1.2 Given Parameters The following parameters are given in the design of the modular robotics system: ➢ Budget - The allotted budget for the project was $1000, given by the IPFW Department of Engineering. The group must spend less than or equal to this $1000. ➢ Mobility - The modular robots must be able to implement at least three different methods of motion. These different types of motions will be accomplished through different configurations of the modules. ➢ Sensors - Two types of spatial awareness are needed to give better control to the modules and prevent the modules from damaging themselves. ➢ Configurations - Each configuration must consist of at least two distinct modules. A single module will not be considered its own unique configuration. 1.3 Design Variables: 1.3.1 Hardware: ➢ Module Construction Materials - Parts such as module connectors and electronic housings should be manufactured through common processes such as plastic injection molding or 3D printing, more common components could be ordered. ➢ Module Communication Medium - Wired or wireless communication between modules with a standardized connector. ➢ Central Control Unit - The central controller unit of the system will operate on an embedded system platform already available for purchase, i.e. Arduino. 1.3.2 Software: ➢ Communication Framework - A communication framework needs to be created to allow for standardized communications for the central control unit to various modules and inter-module communication.
  • 8. 8 ➢ Module Communication Protocol - Depending upon the choice of communication medium, a variety of short-ranged wireless protocols can be used such as Bluetooth, infrared (IrDA), or Wi- Fi. 1.3.3 System Conditions: ➢ Module Timing - The modules will need to be in sync to function properly, this is especially true for movement and communication purposes between multiple modules. 1.4 Limitations and Constraints: ➢ Durability - The modular robot is expected to move along the floor and various surfaces. It should be durable enough to resist wear from movement across these surfaces. The connection between modules must be durable enough to withstand the strain of moving. ➢ Materials - As this robot may need to be handled for swapping out pieces, the rechargeable battery packs, or changing the code, it is of the utmost importance that the robot is safe to handle. 1.5 Additional Considerations: ➢ Other types of modules (Audio, LEDs) - This would add even more features that would be modular attachments to further increase the number of possibilities in setups. ➢ Robot Controller - This could be a way for the user to control the robot without inputting or uploading new code. This could be in the form of a wired or wireless controller, this would be optimal for demonstrations to users who don’t understand code. ➢ Programming Interface - Utilizing a form of wireless communication would allow the modules of the robot to be updated without the need to be physically connected to a computer.
  • 10. 10 2.1 Functional Overview of Module 2.1.1 Overall Overview Throughout the designing of the modular robotic system the given parameters and design constraints were kept in mind when choosing components. Movement, weight, and size were a huge focus when choosing parts. This led the components of the modules to be smaller and more compact, as well as power and resource efficient. Cost was another area of concern because smaller but more powerful components tend to cost more. These constraints and parameters led to the design of a module where some dynamics in movement were sacrificed in order to get a compact and sufficient base module design. In the chosen concept a single base module is used. This base module contains two motors and all the electronics necessary to operate those motors as well as communicate to a master hub. Each module casing has magnetic connections on all sides so that subsequent modules can be added to create a cooperative and moving system. In order to get necessary module movement, two motors were needed. A servo motor is used to create a joint/elbow like motion while a DC motor is used to create a purely rotational motion. A microcontroller is used to run as well as regulate the motors along with some other electronics. All these elements create a single base module with two dynamics in its motion. 2.1.2 Operating Process Overview Figure 1 is a flow diagram that illustrates the process that each module goes through in order to execute a command. Here the message will be transmitted from a transceiver that is connected directly to a computer. This computer will send out the commands for each module and a transceiver inside the module will check them. If the message has pertinent information, like a command or request, then the module in question will continue with the information and execute all the necessary steps. Most messages will be command messages that the micro-controller in the module will pass to the motors making them move in some way.
  • 11. 11 Figure 1: Overview for the per module process.
  • 12. 12 2.2 Controller Board In keeping with the idealistic modular approach with the robot, each module of the system will have a self-contained controller. Utilizing a single PCB we will be able to integrate all electronics, chips, and boards onto a single component that would then be fastened to the module casing. The main components of the controller will include the following: ● Arduino Pro Mini 328 Microcontroller ● 595-INA169NA/3K Current Sensor ● 3.3 V - 595-UA78M33CDCYG3 Voltage Regulator ● LT1085CM Adjustable Voltage Regulator ● Dual TB6612FNG (1A) Motor Driver (DC Driver) ● NRF24L01+ 2.4GHz Wireless RF Transceiver ● Magnetic Encoder for Micro Metal Gearmotors (connected to DC motor) A high-level block diagram for the controller board can be seen in Figure 2 while Figure 3 shows an overall schematic for the connections between these electronics. Figure 2: High-level block diagram for the Controller board.
  • 13. 13 Figure 3: Overall schematic for the Controller board. Two different approaches will be used to control each of the motors. First, a motor driver will be purchased to control the DC motor. This driver allows for a PWM signal to amplify the current available to the motor. Two other inputs allow for the rotational direction of the motor to be controlled or for the motor to be stopped. These pins will be numbers D4 and D5 on the Arduino board. The output of the DC motor driver will then connect to the DC motor and to the DC motor encoder. This digital encoder will allow for the position of motor to be measured up to a resolution of 1/8th of a rotation, outputting the current position to pins D7 and D8 of the microcontroller. Two current sensors are placed on the Vcc pin of the DC motor to detect a stall current regardless of the direction in which the motor is spinning. If a stall is detected on pins A1 or A2 of the Arduino board, the controller will shut off power to the motor.
  • 14. 14 Additionally, the Servo motor will be controlled by another Pulse Width Modulated signal, generated by the D9 pin on the microcontroller. This PWM signal will control the angle at which the servo motor is positioned. The LT1085ISX Adjustable Voltage Regulator was selected to achieve this motor’s operating voltage of 6 volts. Again, a current sensor is placed in series with this regulator to detect the 0.8 amp stall current of the servo motor. The stall current signal from the current sensor will be read by the A0 pin of the Arduino. A photo of the Arduino, including the pin layout, which will be used can be seen in Figure 4. Figure 4: Arduino Pro Mini board from Sparkfun.com. 2.2.1 Microcontroller The used microcontroller for the Controller board will be an Arduino Pro Mini. The particular board is a 3.3V Arduino running at 8MHz. It contains a built in voltage regulator allowing the use of a raw voltage input. In order to save size the board does not containing any connectors (all connections must be soldered on) or any USB/ programming peripherals. This allows for a completely minimalist microcontroller, perfect for the size constrained modules. The schematic for the Arduino can be seen in Figure 5.
  • 15. 15 Figure 5: Schematic for the Arduino Pro-Mini 328 Microcontroller This will be our main brain of each module and will be interfaced in some way to all of the components going inside. The commands for the microcontroller will be programmed in C/C++ and the program will be loaded with an FTDI basic Breakout board with USB connection before it is placed on the main PCB controller board. Using the digital SPI ports it will control the wireless communication via a transceiver. It will also control both motors whether directly with the servo or through a motor driver with the DC. 2.2.2 Current Sensor These components are necessary for monitoring the limits of the robotic system. With loaded motors and voltage sensitive components controlling the current and voltage is a necessity. In the chosen concept, a current sensor is needed for each motor. With one of these sensors in place the module is able to detect when the motors are reaching rated stall current and shut off the necessary components so that none of the motors or electronics are harmed. The voltage regulators are necessary in order to ensure that the voltages supplied to the electronics such as the motor driver and motors are never exceeding the rated.
  • 16. 16 Figure 6 shows the schematic of the current sensors. The selected current sensors detect a small voltage drop across a shunt resistor then converts the detected voltage drop to another voltage via an operational amplifier. According to the datasheet, this sensor works best when detecting a drop of 0.5 volts or less. Another determining factor to using this chip was that the analog inputs of the microcontroller can only detect up to 3.3 volts. Keeping these values and the stall currents of the motors (0.8 A for the Servo motor and 1.6 A for the DC motor) in mind, a variation of Ohm’s Law, seen in Equation 1, and Equation 2 (provided by the datasheet) were used to calculate the necessary resistors. 0.5 𝑉 ≥ 𝐼𝑆𝑆𝑆𝑆𝑆 ∗ 𝑅𝑆 (1) 𝑉𝑂 = (𝐼𝑆𝑆𝑆𝑆𝑆∗𝑅𝑆∗𝑅𝐿) 1 𝑘𝛺 (2) This calculation yields resistor values of RS = 0.4 Ω and RL = 10.2 kΩ for the Servo motor and RS = 0.4 Ω and RL = 5.1 kΩ for the DC motor. In these equations, RS is the shunt resistor and RL is an external resistor used to adjust the needed output voltage. Because RS for the Servo motor is twice that of RS for the DC motor, two 5.1 kΩ resistors will be placed in series to achieve the calculated 10.2 kΩ resistance to reduce the cost of the design. Equation 3 and Equation 4 detail the power calculations that were performed to ensure the resistors could perform as needed. 𝑃𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 = 𝐼𝑆𝑆𝑆𝑆𝑆 2 ∗ 𝑅𝑆 (3) 𝑃𝐶𝐶𝐶𝐶𝐶𝐶𝐶𝐶 = 𝑉𝑂 2 𝑅𝐿 (4) Table 1 shows the results of these calculations. From this table, it can be seen that RS will need to be able to handle at least 1024 mW of power consumption and RL will need to handle up to 2.09 mW of power consumption. The selected resistors for both RS and RL can handle 2 W of power consumption. Table 1: Power Consumption for Current Sensing Resistors Servo Motor DC Motor RS 256 mW 1024 mW RL 1.04 mW 2.09 mW Figure 6: Operational schematic for the current sensor.
  • 17. 17 2.2.3 Voltage Regulators A 3.3 volt and a 6 volt voltage regulator will also be implemented in each board to supply the transceiver and Servo motor respectively. A voltage regulator is not needed for the DC motor because this motor will be implemented with a driver, which will take care of the voltage requirements. Because the power supply in each module operates at 7.4 volts, the voltage regulator will step down the voltage to something more useable by the servo motor or the transceiver. Another reason for their implementation is to minimize voltage drops as motors turn on and off. The main concern when selecting the specific voltage regulator was to ensure that they could supply enough current. According to the transceiver’s datasheet, the maximum current needed will be 13.5 milliamps. The selected 3.3 volt voltage regulator can provide up to 500 milliamps. To supply 6 volts and 1.6 amps to the Servo motor, a fixed 6 volt regulator could not be used. Research showed that a cost-efficient regulator that met these specifications was not available. Therefore, an adjustable voltage regulator will be used. This Regulator can supply up to 3 amps of current, well above the 1.6 amp stall current of the Servo motor. Figure 7 shows the schematic of the adjustable regulator. According to the data sheet, because IAdj ≤ 120 microamps, VREF = 1.25V and if R1 ≈ 100 Ω, Equation 5 could be used to determine the resistance values. From this equation, it was determined that the resistance values needed will be R1 = 100Ω and R2 = 380Ω. 𝑉𝑂 = 𝑉𝑅𝑅𝑅 ∗ �1 + 𝑅2 𝑅1 � (5) A Multisim simulation for the voltage regulator was constructed in order to verify the calculated resistor values. Figure 8 shows that the circuit generates close to the expected 6V using the resistors found from Equation 5. Figure 7: Operational schematic for the adjustable voltage regulator.
  • 18. 18 Figure 8: Simulation for the adjustable voltage regulator. 2.2.4 DC Motor Driver A driver board will be utilized in order to efficiently control the DC motor creating the rotational motion of the modules. A Dual TB6612FNG (1A) Motor Driver was chosen in regards to its ease of implementation with an Arduino. This driver board will allow the microcontroller control over the motors direction as well as speed using outputted PWM (Pulse Width Modulation) signals with a frequency up to 100kHz. The schematic for this driver board can be seen in Figure 9. Figure 9: Schematic for the DC motor driver (Dual TB6612FNG (1A) Motor Driver).
  • 19. 19 2.2.5 Magnetic Encoder for DC Motor An encoder will be used on each DC motor. This will give the microcontroller the ability to send commands to the DC motor (through the driver module) with feedback. For instance, a command could be sent to the motor to turn for 5 revolutions. With the encoder, the module will be able to make counts like this. We chose the magnetic encoder for its ability to be paired with a DC motor with a back shaft. Although limiting the scope of DC motors that could be used in the design, the ability to have better and more precise movement data greatly outweighed the cost. A schematic for the magnetic encoder can be seen in Figure 10. Figure 10: Provided schematic for the magnetic encoder board. 2.3 Wireless Communication The modules will utilize the NRF24L01+ transceiver for wireless communication. This transceiver module supports operating speeds up to 2Mbps as well as low power consumption. It will be implemented into the SPI ports of the Arduino Pro Mini controller. With a transceiver inside each module of the robot, all modules will have communication with the main controlling Arduino board (which is connected to the programming computer). The chosen protocol to use for the communication of the modules is a self-defined raw packet transfer. Although there was an availability of standard wireless communication protocols such as ZigBee (802.15.4), Wi-Fi (IEEE 802.11), and Bluetooth (IEEE 802.15.1) the raw packet transfer was found to be sufficient in both cost and implementation. The protocol will utilize an array of 32 bytes, not all of which will be used. The array will contain a byte for the message type, a byte for a message ID, and 30 separate bytes containing messages pertinent to a single module. Each module will receive the array but will only index the message type, the message ID, and two bytes of data specific to that module. The two bytes of module specific data will then contain first 8 bits, 4 of which tell the degree of the servo motor, 1 bit for the direction of the DC motor, and 3 bits for the speed of DC motor and then 8 more bits containing encoder count details. This will allow the servo motor to work with a degree resolution of about 6 degrees, the DC motor to tell which direction it should be going, 8 different speeds for the DC motor, and the number of revolutions for the DC motor. An overview of the protocol array can be seen in Figure 11.
  • 20. 20 Because not all 32 bytes of the array are utilized, this protocol could very easily be expanded to work with even more modules or more bytes dedicated to a single module. Also, it is well-known that bit errors can occur over communication especially with wireless transmission. With so much extra room in the communication array, encoding (such as Hamming or Convolutional encoding) could be utilized in order to detect and correct errors. Utilizing past projects, code for this encoding and decoding is available with the work coming from integrating the code into our protocol. Also, the chosen transceiver (NRF24L01+) has built in CRC coding which is also used to detect and correct errors in wireless communication. Figure 11: Overview diagram of the communications protocol. 2.4 Motors and Battery 2.4.1 Picking the Motors and Batteries In order to select the motors and battery several factors were kept in mind; torque, voltage/current, and weight. These motors had to be small enough to fit in the modules but strong enough to lift another module. Since the voltage, current, and weight were a major factor it was decided to determine the battery before the motors as the battery would have the most mass and would limit the possible motors. After looking at various batteries and the available space it was decided that two batteries with a voltage of 7.4V and are rated at 800mAh would be used. A charger was also found that would be compatible with the lithium polymer batteries to recharge the batteries when needed. A DC motor and a servo motor were then found that were small enough to fit in the design, yet strong enough to perform the needed tasks. The DC motor has a torque of 2.16 kg*cm at 6 V and a stall current of 1.6A. Likewise, the servo motor has a torque of 5.5 kg*cm at 6 V and a stall current of 0.8 A. Because the DC motor focuses on the rotational motion, the calculations depend on the radius of the object being rotated, which will be either the wheel or another module. The calculation to find the
  • 21. 21 amount of mass the DC is able to move for a radius of the wheel (3.81 cm) and module (5.388 cm) connected to the DC motor be seen in Table 2. For the servo calculations it is assumed that the average mass that the servo motor has to move will be between 3-6 inches away from the axis of rotation, as each module is 3 inches long. The calculations for the amount of mass the servo can move at the lower end of 7.62 cm (3 in) and the upper end of 15.24 cm (6 in) can be seen in the lower half of Table 2. Table 2: The mass calculations for the DC motor and servo motor. Based on these measurements a module would have to have a mass of 369 grams or less for the servo to be able to move another module. To verify these values work, a table of the masses of each component was created, Table 3. Table 3: The estimated mass of a single module based on components. Motor Torque (kg*cm) Radius (cm) Mass (kg) 3.81 0.567 5.388 0.401 7.62 0.722 15.24 0.361 DC Motor Servo Motor 2.16 5.5
  • 22. 22 Based on the combined mass from Table 3, both of the motors have enough torque to lift/turn an adjacent module, which will greatly increase the mobility and connections made available when assembling modules. 2.4.2 Power Calculations Based on the max possible current a component will draw from the battery and voltage consumption of the components attached to the battery it was possible to calculate a worst case power consumption. These values can be seen in Table 4. The total power was found to be roughly 14.57 Watts and is manageable by the batteries. Based on the batteries mAh rating of 800 mAh the batteries will last roughly 36 minutes (based on total current draw from the table). Since this is the worst case scenario it is expected that the batteries will last much longer. Table 4: Worst case power consumption of the module. 2.5 Casing 2.5.1 Casing Overview The casing and parts for 3D printing were developed and modeled in SolidWorks. The casing was broken up into different sections for printing, these sections are; the 4-sided casing, a wall insert, a casing wheel, and plastic inserts (4 for each module). The print time for these components can be seen in Table 5. The 4-sided casing will be the largest section and will be a base for all the other parts of the casing. The wall insert will slide into the base and connected using screws. The casing wheel will be connected on the open top of the module, it will connect to a shaft hub that comes from the DC motor. The plastic inserts will go in each wall and separate the magnets and sheet metal disks from the inside of the module. The bottom of the module will not have a plastic insert as the servo motor will be using some of the space that the insert would take up. Component Voltage Drop (V) Amps (A) Watts (W) DC Motor Encoder 7.4 0.060 0.444 DC Motor Driver 7.4 1.600 11.840 Arduino 7.4 0.150 1.110 6V - Adjustable Regulator 1.4 0.800 1.120 3.3 V - Fixed Regulator 4.1 0.014 0.055 2.624 14.569 Total
  • 23. 23 Table 5: The different components that will need to be printed per module. The total printing time required for all the components is roughly 14.6 hours. This is with a 10% fill in the walls of the module. For explanation purposes the top of the module will be refer to the open end where the wheel attachment is connected. All of the electronic components will be placed on a PCB mounted on the wall opposite of the removable wall insert. On the two walls adjacent to the electronics the batteries will be placed, one on each side. This will help to balance the weight of the module as the batteries are the heaviest components. The servo motor will be on the floor of the module and turn a shaft that will be supported from a bracket. This shaft will then connect to the DC motor with a bracket, which will connect to the shaft hub, and then onto the wheel at the top of the module. This setup can be seen in Figure 12. Views of the other SolidWorks models (4-sided case, wheel, inserts, etc.) can be seen in Figures 13-17. For a complete view of the 3D printed elements refer to Appendix A. Figure 12: Overall view of the constructed module.
  • 24. 24 Figure 13: Overall dimension of assembled module. Figure 14: Views showing the center of mass (purple coordinates). From the absolute center of the module, the center of mass is X= -0.25, Y = 0, Z = 0.05.
  • 25. 25 Figure 15: Explosion view of DC motor assembly and wheel. Figure 16: Explosion of the wall casing and insert.
  • 26. 26 Figure 17: Explosion of the servo assembly and casing. 2.5.2 3-D Printer Settings The MakerBot Replicator 2 3-D printer will be used to create the casing and all of the plastic pieces attached. The printer is capable of printing with a resolution of 100 microns. Figure 18 shows the settings using the MakerBot Desktop printing software. As shown, the casing will only have a 10% fill. The MakerBot 3-D printer uses a honeycomb filling structure and provides for very strong walls without the need to completely fill them. Setting the casing to 10% greatly reduced the amount of used material greatly lowering the weight and cost.
  • 27. 27 Figure 18: Screen capture of 3-D printer settings. 2.6 Changes to the Initial Design: Several design changes were made to alleviate issues encountered during the implementation of the initial concept. 1. Locking Mechanism - Due to inconsistencies in the 3D printing of the module casings, magnets could not be reliably used to connect modules. Instead, a Velcro pattern was developed that could perform in the same manner as the magnets as seen in Figure 19. This pattern had alternating hook and loop structures to securely connect modules together. Figure 19 - Alternating hook and loop Velcro pattern used for inter-module connection.
  • 28. 28 2. PCB to Protoboard - Development of a PCB for the modules had to be cancelled due to time constraints. Instead, components were wire-wrapped on a protoboard. This allowed for straight forward troubleshooting and ease of board rearrangement. During this transition, the current sensor was removed from the board because of size restraints and inability of integration. 3. 3-D Printed Design – Changes had to be made to the casing to accommodate the protoboard. Additional battery holders were extruded from the servo bracket and the insert wall to better hold the batteries in place. 4. Controller Implementation - It was decided to implement a controller to ease the use of the modules,. This decision eased development in three ways. First, code to control the modules only needed to be re-downloaded once to the controller opposed to needing to re-downloaded to each module. Second, the controller allowed for dynamic control of the modules instead of relying on a preprogrammed set of instructions. Third, the controller eliminated the need for spatial awareness sensors within each modules, as errors could be dynamically corrected by the user. 5. DC Motor Encoder - Although an encoder was integrated with each DC motor in the modules, code to utilize the encoder was not developed for the microcontroller. It was deemed unnecessary due to the implementation of a controller. 6. Wireless Protocol - Some changes were made in the wireless protocol. The new protocol is outlined below: RFRxBuffer[0] = Message type RFRxBuffer[1] = Message ID number RFRxBuffer[(ModID + 1) * 2] = ((servoAngle << 3)&0xF8) | ((servoSpeed << 1)&0x06) | (dcDir&0x01); RFTxBuffer[(ModID + 1) * 2 + 1] = dcSpeed; RFRxBuffer[]: an array used to store the data received from the transceiver. ModID: the ID number of the module. Each module has a unique ID which allows it to find its data from the array. The addresses can range in value from 0 to 14 due to the transceiver only being able to transmit 32 bytes at a time. For this project, only 24 bytes were transmitted at a time. servoAngle: a 5-bit variable that tells the module where to align the servo motor. servoSpeed: a 2-bit variable that tells the microcontroller how fast to move the servo motor. It was found at some fast speeds, the servo motor would move violently. dcDir: a 1-bit variable used to spin the DC motor clockwise or counter-clockwise. dcSpeed: an 8-bit variable used to determine how fast the DC motor should spin.
  • 29. 29 2.7 Final Prototype Design After making the alterations mentioned above, 4 main modules and 1 backup module was developed and can be seen in Figure 20. Each module consists of a controller board, two parallel batteries, a servo motor, DC motor, encoder, interlocking velcro, and several 3D printed parts. Figure 20 - A total of 4 main modules and 1 backup module (not pictured) made for this project.
  • 31. 31 3.1 Prototype Construction 3.1.1 Casing and Brackets: The reconfigurable module robots are three inch cubes. The casing and brackets were 3D printed using a makerbot replicator 2. They were printed with seven percent fill, four shells, and a layer height of 0.2mm. Table 6 below shows the eight 3D printed parts. The parts were created in SolidWorks. Major changes from the design phase included adding battery blockers to the servo bracket, this difference can be seen in Figure 21. This change was made so the batteries would avoid hitting the DC bracket while the module is moving. Another change was adding battery blockers to the insert wall to prevent the batteries from sliding out of the module, this change can be seen in Figure 22. Some changes to the main casing included the addition of a wider slot in the back of the module for the protoboard as well as the removal of the battery brackets since they were moved to the insert wall, these changes gave more room inside the module. These changes can be seen in Figure 23. The two halves of the DC holding bracket can be seen in Figure 24, the servo to DC connector can be seen in Figure 25, and the wheel and wheel insert can be seen in Figure 26. Table 6: The parts that were 3D printed. 3D Printed Parts Casing 4-sided Casing Wall Insert Casing Wheel Wheel Insert Servo to DC Connector Servo Bracket DC Holding Bracket (Left) DC Holding Bracket (Right) Figure 21: The original design to the servo bracket (left).The improved servo bracket with the battery blockers (right).
  • 32. 32 Figure 22: The original design to the insert wall (left). The improved insert wall with the battery blockers (right). Figure 23: The original design to the module case (left). The improved module case without the battery blockers and additional slot in the back (right).
  • 33. 33 Figure 24: The two halves of the DC bracket. Figure 25: The connecting piece between the servo motor and DC brackets. Figure 26: The wheel (left) and wheel insert (right) which are connected to the DC motor for rotation.
  • 34. 34 3.1.2 Module Protoboard: The module circuit boards were created using a cut piece of protoboard. These boards were measured and cut to be small enough to fit inside the casing but large enough to remain stationary when the module was moving. A circuit diagram of the module board can be seen in Figure 27 and a detailed view of the actual boards can be seen in Figure 28. The protoboard housed all necessary IC’s and chips in order to run the modules. This includes the microcontroller, transceiver, DC driver, an adjustable voltage regulator, and several connections for batteries and the two motors. In order to tie all of these components together, hand-done wire wrapping was utilized. This provided a simple and efficient way to create, test, and make changes to the boards as seen fit. A view of the back side of the board showing the wire wrapping can be seen in Figure 29. Figure 27: Multisim schematic for the module boards.
  • 35. 35 Figure 28: Detailed view of the module boards. Figure 29: View of the back side of the module boards showing the wire wrapped connections. The microcontroller utilized inside the modules was an Arduino Pro Mini. This ATMega328 board contained all necessary pins to drive the wireless communications, the servo data lines, as well as the PWM signals needed for the DC driver to run the DC motor. It also had the necessary unregulated voltage input needed for direct integration with the chosen 7.4V batteries. This board is the brain of each module, decoding and communicating needed signals to all necessary components for movement.
  • 36. 36 On the wireless communication side, the nRF2401 transceiver was utilized. This transceiver provided great range with communication as well as integrated CRC or Cyclic Redundancy Check encoding for error detection. The nRF2401 was also used because of the wealth of communication examples, tutorials, available libraries, and ease of integration with the desired and ultimately used protocol. One trouble that did occur with the board came when attempting to solder to the attached header pins. When trying to solder wires to the pins, the transceiver would malfunction and halt communication with the controller. Once discovered this was easily fixed by the sole use of wire wrapping. Another important component on the module board is the DC driver. This small board allowed the Arduino, and thus the controller, precise and adaptable control over the DC motor. Utilizing a PWM signal from the Arduino, the board was able to change and control the speed of the motor. It also allowed for easy direction changes with the addition of two digital signals from the Arduino. All of these components, along with a voltage regulator and various connections to the motors and batteries, are located on this single board that fits inside the module. These electronics are housed and utilized within each of the modules and only need communication from the controller in order to make a working and moving robot. 3.1.3 Controller Protoboard: Protoboard and wire wrapping were again used when creating the controller. A schematic of the controller board can be seen in Figure 30. Additional views of the controller’s front and back showing the electronics as well as the wire wrapping done to connect and secure each component can be seen in Figures 31-32. This controller used some similar components seen in the module boards, such as the transceiver and an Arduino microcontroller. The controller board does contain some different components including two joysticks, an ON/OFF toggle switch, and three LED’s. As a whole, this controller board allowed for easy programming to fit the needs of different configurations as well as an easy and efficient way to control the modules.
  • 37. 37 Figure 30: Multisim schematic for the controller board. Figure 31: Front view of the controller board.
  • 38. 38 Figure 32: View of the back side of the controller board showing the wire wrapped connections. A different Arduino was chosen for the controller. This time an Arduino Micro was utilized because it allowed for more inputs and outputs needed for the joysticks, transceiver, and LED’s. It also ran at a higher frequency, 16 MHz, which allowed for prompt outputted wireless commands to the modules. The same transceiver (nRF2401) that was used in the modules was implemented in the controller. This transceiver was definitely the work-horse of the bunch, sending out the command packets to all of the modules that would then receive and decode their specific instructions. The joysticks and their attached breakout boards are the main interaction between the program running the controller and modules and the human controlling them. Using the two potentiometers for each axis, the controller was set up to have the servo motor associated with left and right movement and the DC controlled by up and down movement. This allowed for different servo angles depending on slight variations of the joystick as well as quick DC speed and direction changes. Also, a built in button allowed for an even more adaptive use of the controller. Using the button, the human controller is able to switch between different modes on the fly. The utilized modes were a single module control mode, a configuration control mode, and a servo calibration mode. Indications lights, the LED’s, were added in order for the human controller to know the mode that the controller was in as well as which configuration or module was being controlled at a certain time. A detailing of the different controller modes and their associated LED indication can be seen in Table 7.
  • 39. 39 Table 7: The LED outputs on the controller and the associated modes. 3.1.4 Assembling Process: In order to assemble the modules, the following steps must be completed: 1. First, slide the servo motor into the servo bracket, making sure to have the wires going toward the notched end of the bracket (Figure 33 - top left). 2. Next, with the DC motor shaft hub and 3D printed wheel securely connected to the DC motor, attach the DC motor brackets (Figure 33 - top right). This requires the printed servo to DC connector piece to be securely on the DC bracket peg (Figure 33 - bottom). Make sure to solder the DC magnetic encoder directly onto the DC motor before attaching the brackets. 3. With the motors prepared, slide the metal rod through the servo bracket hole and mount the DC motor to the servo (Figure 34). Make sure to connect the servo to DC connector to the second hole of the servo arm.
  • 40. 40 Figure 33: Servo motor and bracket (Top-Left). DC motor and bracket (Top-Right). Servo to DC connector (Bottom). Figure 34: Completely assembled motor housing with servo motor and DC motor connected brackets. 4. With the motors completely assembled together, plug the servo motor into the 3-pin servo connection on the module board. The ground for the servo is located closest to the Arduino. Attach the DC wires from the encoder on the DC motor to the pins on the module board. Make sure to make the correct connections (M1 and M2 are the pins closest to the DC driver).
  • 41. 41 5. At this point, carefully connect the batteries to the module board. Double check before plugging the batteries in that the RED wire is facing toward the inside of the module board. Figure 35 shows the made connections between the board and the batteries, servo, and DC/encoder. Figure 35: Correctly connected DC, servo, and batteries. Note the direction of the battery wires and the servo connector. 6. Next, carefully take the connected board and components and gently put them into the main module casing. Have all the components sit securely but have them loose enough for the servo motor to move freely. The batteries may become unconnected at this point which requires the removal of the board and all components so they can be again correctly connected. 7. Finally, carefully put the wall insert into the channel and guide it to the seated position paying close attention to the wires and their positions in the module. At this point the module is complete with all components secure and unmoving except for the servo which should be free to cover all of its angles. Figure 36 shows all of the components inside the module without the wall insert (left) and the completed and fully assembled module (right).
  • 42. 42 Figure 36: Module with all electronics carefully placed inside (Left) and the complete and fully assembled module (Right). 3.1.5 Software Development: There were two sets of code used during this project, the code for the Arduinos inside the modules and code for the controller. All the modules used nearly identical code, the one difference is a ModID variable which represents the identification number of the module. The number is used to designate which section of the wireless packet the module will grab the commands from. After the module code looks through the received data and determines which commands to execute it sends the needed signals to the DC and servo motor. There is also a section of the code to calibrate the servo motor, which changes the base angle that the servo is set to. This is to allow for adjustments if the servo connection to the DC bracket is misaligned. The module code can be seen in Appendix B and an overview of the module code process can be seen in Figure 37.
  • 43. 43 Figure 37: Flowchart detailing the module code. The controller code is used to take the signals from the two joysticks and transmits the corresponding commands to the modules. To make sending commands easier in the code the function toModule was created, which takes the parameters: the module ID, servo angle, servo calibration, DC direction, and DC speed. It then puts these values in the correct section of the RFTxBuffer to transmit out to the modules. The controller has different states that it represents using the LEDs on the controller. The red LED represents the overall mode, while the two yellow LEDs represent the different sections of the mode. Initially the red LED is off, which represents single module control, where each joystick can control a single module. In this case the yellow LEDs represent which modules are being controlled, which could be 0 and 1, 2 and 3, etc. Since there are not modules for all the available the fourth state is currently set to control 1 and 2 to allow for more options during the testing phase. The next mode is to control configurations, this mode is represented with the red LED being dimly lit. In this case the yellow LEDs represent the wheeled, caterpillar, and buffer configurations, which are states 0-2, respectively. The wheeled state sets the servos to a fixed angle on modules 0-3 so the wheels are touching the ground. The left joystick is then responsible for the DC motors of 0 and 1, while the right controls the DC of 2 and 3. The caterpillar configuration uses the forwards and backwards of the right joystick to cause the servos to move in a wavelike motion. This is done through the use of a while loop, when held forward the joystick will start the wave motion at the front, and pointing in the backwards direction will cause the wave to start at the back. By holding the left joysticks forward it will cause the modules to straighten out, moving the servo to the default set position. Currently in order to turn the caterpillar motion the mode has to be switched to the single module mode, which will allow for the lead modules DC motor to be turned to
  • 44. 44 rotate the wheel and change direction. The buffer configuration is much like the wheeled configuration, but the servos are set at the default position so they can’t be turned when spinning the DC motors. The code for the controller can be seen in Appendix C as well as the flowchart in Figure 38. Figure 38: The flowchart of the controller software.
  • 45. 45 3.2 Prototype Cost Breakdown Many components were purchased in order to complete this project. Table 8 shows the cost breakdown for the completed modules. These were all of the components used in the module boards, casing, and controller. As shown the total cost of the completed project was $753.92. Taking away the components used solely for the controller gives the total module cost $720.97 driving the cost per module (given that enough materials were present to make 6 modules) to $120.16. This was a very important aspect in the design. For the project as a whole to be low-cost, the cost of the modules had to be as cheap as possible. Table 8: Cost breakdown for the completed Module Robot project. It is also important to note the comparison between the 1st semester project estimate and cost per module also noted in Table 8. The 1st semester budgeting predicted a total project cost of $671.71. Although seemingly more, this semester’s total cost includes enough materials to make 1 more additional module compared to the first semester’s five. Also, taking out some of the components such as the magnets, the metal plates, the current sensors and associated resistors, and other various PCB components lowered the
  • 46. 46 price of the cost per module about $14.00. Table 9 details the components that were purchased but were not utilized in the final design. Although accounting for $82.84 of our budget, these components could be utilized in a later project to incorporate a PCB design for the modules. This gives us a total amount spent of $836.76. Table 9: Cost breakdown of purchased but unused components.
  • 48. 48 4.1 Testing Requirements and Methods 4.1.1 Three Types of Motion: The first requirement that the modules had to complete is three different types of motion from different configurations. The group came up with three types of configurations that use different forms of motion. The first type is a wheeled configuration. This type has the wheel end of the module facing outward, where the servo is then able to point the wheels downward to lift the modules up. By rotating the wheel with the DC motor it is possible to move the modules forward, backwards, and turn based on the speed difference of the wheels. This configuration is the fastest configuration, which has the ability to travel over slight elevation changes and many different types of surfaces. This type of configuration can be seen with two modules in Figure 39, and four modules in Figure 40. Figure 39: The wheeled configuration using two modules. Figure 40: The wheeled configuration using four modules. The second configuration created was a buffer type motion. This was implemented by having the wheel end of the module pointing down toward the floor. As the wheel spins it can allow the module to rotate around a non-spinning module or in a specific direction depending on which modules are spinning. This configuration allows it to move in almost any two dimensional direction, but cannot travel over different elevations or on a loose surface. This this type of configuration can be seen with two modules in Figure 41, and four modules in Figure 42. Figure 41: The buffer configuration using two modules.
  • 49. 49 Figure 42: The buffer configuration using four modules. The final configuration that was created was a caterpillar like motion. In this configuration the modules are assembled in a line with the wheeled face pointing forward for all modules. This configuration oscillates the servos in a wavelike pattern from front to back or back to front lifting the modules in a caterpillar like movement. The front module can be used to turn the configuration by pointing the wheel to the ground and using the DC motor to turn the wheel. This is the slowest configuration, the wavelike motion pushes the modules forward toward the wheel end, can lift itself over a greater elevations than the others, and can turn using the leading module. This this type of configuration can be seen with two modules in Figure 43, and four modules in Figure 44. Figure 43: The caterpillar configuration using two modules. Figure 44: The caterpillar configuration using four modules. 4.1.2 Movement Accuracy: In order to prove that the modules could be moved accurately using the controller a course was set up with a ten foot distance to a square foot goal. This test was used to show that each configuration could move successfully and in an accurate manner. Each configuration proved that it could be navigated into the goal, which satisfied our requirement.
  • 50. 50 4.1.3 Battery Lifespan: From the first semester calculations it was predicted that at maximum load of the servo and DC motor the batteries would last roughly 36 minutes. To ensure that the modules could be used for a significant time without needing recharged a goal of at least 20 minutes was set. No load conditions were first checked by allowing the servo to be set at an angle and the DC motor to run continuously. This test was stopped after 4 hours and 30 minutes, the DC motor was still spinning but was beginning to overheat. While other testing was in progress the modules were subjected to varying amounts of load and it is estimated that the batteries will last at least 2 hours without major effects to the performance of the motors. Based on these tests it was concluded that the modules would last much longer than our 20 minute goal of normal usage. 4.1.4 Prototype Weight: In the first semester it was estimated that the maximum weight our modules could be is 400 grams. This is based on the torque of the servo and DC motors, our goal was to be under this 400 grams. From the initial parts it was estimated that our modules would be around 330 grams. After construction the weight of the modules was found to be 275 grams. This difference was due to the replacement of many of the metal parts with light weight alternative, as well as changes to the casing design that required less plastic and a lower fill rate. Based on this found weight the modules meet our requirements for this test. 4.1.5 Wireless Communications Distance: The final test that was performed was a communications distance test. A distance of at least 30 feet in open air was set for this goal. This is to ensure that the user has full control of the module when using the controller from a reasonable distance of view. When tested in open air conditions the module was able to receive commands sent from the controller at a distance of roughly 50 feet, which meets our predefined goal.
  • 51. 51 Section V: Conclusions and Recommendations
  • 52. 52 5.1 Conclusions These prototypes meet the design goals and specifications set forth at the beginning of this project. Each module has an Arduino which allows them to be reprogrammable for future designs or additional sensors to be implemented. All modules have two batteries, so the power is non-restricting and rechargeable. The group spent $836.76, which is less than the budget of $1000. The group was able to assemble three different configurations, comprising of at least 2 modules, each utilizing a different form of motion. Because a controller was implemented such that a user could dynamically alter the movement of a configuration, the requirement for two types of spatial awareness was deemed inapplicable to the design. It is considered that the user of the controller acts as the sensors rather than the module utilizing sensors of its own. The modules do still have an encoder connected to the DC motor to measure how the fast the DC motor is spinning, but it is not currently utilized by the module software. The prototypes also meet all the testing requirements that were set. Each configuration was able to perform a unique type of motion and be accurately controlled at a reasonable distance. The batteries proved to supply enough power to keep the modules running for over an hour of use. The modules are also within the weight goals to ensure the motors are able to move correctly. Overall, the group is proud to know that the IPFW department of engineering is fully satisfied with the prototypes built, and are considering using them for future projects and continuing to make advancements to the design. The team would like to thank our advisor, Dr. Liu, for helping us through each stage of the design and implementation process. 5.2 Recommendations One way in which the design could be improved by adding an On/Off switch to the modules. Currently the batteries must be removed to turn the modules off which requires the modules to be disassembled. Adding a switch would simplify the process and allow the modules to stay assembled and be reset with much more ease. Another improvement could be the switch from the protoboard to a PCB. This would help reduce the space it takes up as well as allow for a more streamlined production of boards and modules. The group initially worked toward a PCB, was running low on time, and had issues such as the transceiver not functioning after being soldered on the board. This was due to the solderer overheating the transceiver. A third improvement to the board would be a fuse or diode for circuit protection. As of right now if either battery is plugged in backwards it would fry the Arduino, making it unusable. Currently the encoder is not utilized by the module code, but pins are wired to from the microcontroller to the encoder output pins of the protoboard. By adding the encoder and modifying the code to react to encoder values, it would be possible to reduce the difference between how fast each DC motor spins. This would allow for better control of the modules.
  • 53. 53 One weak point in the current design is the connection between the DC bracket and servo bracket, which uses a small 3D printed connection. This piece is prone to breaking when the there is a significant load that the servo is attempting to lift. By replacing this piece with a stronger material, such as metal or redesigning the connection completely, this will greatly improve the overall strength of the design. The final recommendation would be to use a 3D printer with a better resolution. This would allow for parts to be more identical and reduce the amount of work needed to get the parts to fit together.
  • 54. 54 Appendix A Four Sided Module Casing Servo Bracket
  • 56. 56 Appendix A (cont.) Casing Wall Insert Casing Plastic Insert
  • 58. 58 Appendix B: Source Code for Module //--------------------------------------------------------------------------------------- //Filename: src_module.ino //Project: Low-Cost Reconfigurable Modular Robots //Code: Master Transmitter //By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groff //Course: ECE 406 - Senior Design II //Created: January - April, 2015 //--------------------------------------------------------------------------------------- #include <nRF24L01.h> #include <RF24.h> #include <RF24_config.h> #include <SPI.h> #include <Arduino.h> //MODULE ID int ModID = 3; uint8_t dcDirection; uint8_t encoderSpeed; // // transceiver hardware configuration: ATMega // #define CE 9 #define CS 10 #define ROLE 7 #define BAUD 57600 RF24 radio(CE, CS); // // Topology // // Radio pipe addresses for the 2 nodes to communicate. const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; //Initalize transceiver buffers #define BUFFERLENGTH 24 uint8_t RFTxBuffer[BUFFERLENGTH]; uint8_t RFRxBuffer[BUFFERLENGTH]; //DC Motor Information int PWMA = 6; //Speed control int AIN1 = 4; //Direction int AIN2 = 5; //Direction
  • 59. 59 //Encoder Information int encoder0PinA = 7; int encoder0PinB = 8; int encoder0Pos = 0; int encoder0PinALast; int encoder1PinALast; int encoderPin0; int encoderPin1; int MSpeed; int tics4rev = 600; //Servo Motor Information int servo = 3; int servoMid = 96; int servoMax = 102; int servoMin = 90; int updateCheck = 0; uint8_t prevServoAngle = 97; uint8_t servoAngle = 97; uint8_t servoSet = 0; void clearBuffer(uint8_t *buf) { for (int i = 0; i < BUFFERLENGTH; i++) { buf[i] = 0x00; } } void clearBuffer(uint8_t *buf, int startByte) { int i = startByte; for (i; i < BUFFERLENGTH; i++) { buf[i] = 0x00; } } void sendTxBuf() { radio.stopListening(); radio.write( &RFTxBuffer, sizeof(RFTxBuffer) ); // Now, continue listening radio.startListening(); } int serial_putc( char c, FILE * ) { Serial.write( c ); return c;
  • 60. 60 } void printf_begin(void) { fdevopen( &serial_putc, 0 ); } void setup(void) { // // Print preamble // Serial.begin(BAUD); printf_begin(); printf("Modular Robot Projectnr"); printf("Module Adress: %dnr", ModID); // // Setup and configure rf radio // clearBuffer(RFTxBuffer); clearBuffer(RFTxBuffer); radio.begin(); // optionally, reduce the payload size. seems to // improve reliability radio.setPayloadSize(BUFFERLENGTH); // // Open pipes to other nodes for communication // radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1, pipes[0]); radio.powerUp() ; radio.startListening(); //radio.enableDynamicPayloads(); // // Dump the configuration of the rf unit for debugging // radio.printDetails(); //Establish DC Motor Information and Encoder Values //pinMode(STBY, OUTPUT);
  • 61. 61 pinMode(PWMA, OUTPUT); pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT); pinMode (encoder0PinA, INPUT); pinMode (encoder0PinB, INPUT); encoder0PinALast = digitalRead(encoder0PinA); encoder1PinALast = digitalRead(encoder0PinB); pinMode(servo, OUTPUT); } void loop(void) { ///////////////////////////////////////////Transceiver/////////////////////////////////// int i = 0; if (Serial.available() > 0) { printf("Sending: "); while ((Serial.available() > 0) && (i < BUFFERLENGTH)) { // read the incoming byte: RFTxBuffer[i] = Serial.read(); printf("%02x ", RFTxBuffer[i]); i++; // say what you got: if (Serial.available() <= 0) { sendTxBuf(); clearBuffer(RFTxBuffer); printf("n"); } } } if ( radio.available() ) { // Dump the payloads until we've gotten everything // bool done = false; printf("Received: "); //while (!done) //{ // Fetch the payload, and see if this was the last one. //done = radio.read( &RFRxBuffer, BUFFERLENGTH ); //} radio.read( &RFRxBuffer, sizeof(RFRxBuffer) ); for (int j = 0; j < sizeof(RFRxBuffer); j++) { printf("%02x ", RFRxBuffer[j]); } /////////////////////////////////////////////^TRANSCEIVER^///////////////////////////////
  • 62. 62 servoAngle = RFRxBuffer[(ModID + 1) * 2]; servoAngle = servoAngle >> 3; servoSet = RFRxBuffer[(ModID + 1) * 2]; servoSet = servoSet >> 1; servoSet = (servoSet & '00000001'); servoAngle = servoAngle + servoMin; if ( (servoAngle >= servoMin) & (servoAngle <= servoMax)) { if (servoAngle > prevServoAngle) { while (servoAngle > prevServoAngle) { prevServoAngle = prevServoAngle + 1; analogWrite(servo, prevServoAngle); delay(25); } } else { while (servoAngle < prevServoAngle) { prevServoAngle = prevServoAngle - 1; analogWrite(servo, prevServoAngle); delay(25); } } } if (updateCheck == 0) { if (servoSet == 1) { servoMid = servoAngle; servoMax = servoAngle + 6; servoMin = servoAngle - 6; updateCheck = 1; } } if (servoSet == 0) { updateCheck = 0; } dcDirection = RFRxBuffer[(ModID + 1) * 2]; dcDirection = dcDirection & 0x01; encoderSpeed = RFRxBuffer[((ModID + 1) * 2) + 1]; move (1, encoderSpeed, dcDirection); clearBuffer(RFRxBuffer); printf("n"); } } void move(int motor, int speed, int direction) { //Move specific motor at speed and direction //motor:1 for A //speed: 0 is off, and 255 is full speed //direction: 0 clockwise, 1 counter-clockwise
  • 63. 63 //digitalWrite(STBY, HIGH); //disable standby boolean inPin1 = LOW; boolean inPin2 = HIGH; if (direction == 1) { inPin1 = HIGH; inPin2 = LOW; } if (motor == 1) { digitalWrite(AIN1, inPin1); digitalWrite(AIN2, inPin2); analogWrite(PWMA, speed); } } void stop() { //enable standby //digitalWrite(STBY, LOW); }
  • 64. 64 Appendix C: Source Code for Controller //--------------------------------------------------------------------------------------- //Filename: src_controller.ino //Project: Low-Cost Reconfigurable Modular Robots //Code: Master Transmitter //By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groff //Course: ECE 406 - Senior Design II //Created: January - April, 2015 // //This code was developed to implement the master transmitter to control //a modular robot. The master transmitter uses a SparkFun 5V, 16MHz embedded system //along with an nRF24L01+ transceiver. Commands are sent via the transmitter //and decoded by each module. Each module runs an instance of the src_module.ino //program. The src_module.ino program handles the decoding and execution of the payloads //created by this program and transmitted by the transceiver. // //Arduino Pin Connections // //A0 - Right Stick Horizontal //A1 - Right Stick Vertical //A2 - Left Stick Horizontal //A3 - Left Stick Vertical //D2 - //D3 - Left State Light //D4 - //D5 - Right Stick Z //D6 - Left Stick Z //D7 - Right State Light 0 //D8 - Right State Light 1 //D9 - //D10 - //D11 - //D12 - //--------------------------------------------------------------------------------------- //Include files #include <SPI.h> #include <RF24.h> #include <Arduino.h> //Debug options #define TX_DEBUG; //Transceiver TX/RX data #define JST_DEBUG; //Joystick data //Transceiver hardware configuration and instantiation
  • 65. 65 #define CE 9 #define CS 10 #define BAUD 57600 RF24 radio(CE, CS); // Radio pipe addresses for master/module communication const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; //Initalize transceiver buffers #define BUFFERLENGTH 24 uint8_t RFTxBuffer[BUFFERLENGTH]; //Buffer used for transmissions uint8_t RFRxBuffer[BUFFERLENGTH]; //Buffer to store received data //Initialize controller states = [Left stick, Right stick] // Left 0 = Preprogrammed controlled configuration // Left 1 = Controller controlled configuration // Left 2 = Individual module control // Right 0 = Preprogrammed configuration selection // Right 1 = Controller configuration selection // Right 2 = Module*2 (left stick) and Module*2+1 (right stick) selection int controllerState[2] = {0, 0}; //Initialize controller configuration const int leftStateLight = 3; const int joyRightZ = 5; const int joyLeftZ = 6; const int rightStateLight0 = 7; const int rightStateLight1 = 8; //Array storing joystick information. Pinout: [LV, LH, LZ, RV, RH, RZ] = [A0, A1, D5, A2, A3, D6] //Note: Voltages for right stick run 0-5V bottom to top, left to right. //Note: Voltages for left stick run 5-0V bottom to top, left to right. int joyState[6] = {512, 512, 1, 512, 512, 1}; //Used to keep track of the waves going through the snake/catepillar. int wave = 0; //Sets the servo angle if needs to be changed int set = 0; void clearBuffer(uint8_t *buf, int n) { for (; n < BUFFERLENGTH; n++) { buf[n] = 0x00; } } void sendTxBuf() { //Increase Message ID
  • 66. 66 RFTxBuffer[1] = RFTxBuffer[1] + 1; radio.stopListening(); #ifdef TX_DEBUG printf("Sending: "); for (int i = 0; i < BUFFERLENGTH; i++) { printf("%02x ", RFTxBuffer[i]); } printf("n"); #endif radio.write( &RFTxBuffer, sizeof(RFTxBuffer) ); delay(1); radio.write( &RFTxBuffer, sizeof(RFTxBuffer) ); delay(1); radio.write( &RFTxBuffer, sizeof(RFTxBuffer) ); // Now, continue listening radio.startListening(); } int serial_putc( char c, FILE * ) { Serial.write( c ); return c; } void printf_begin(void) { fdevopen( &serial_putc, 0 ); } void toModule(int address, int servoAngle, int servoSpeed, int dcDir, int dcSpeed) { RFTxBuffer[(address + 1) * 2] = servoAngle << 3 | servoSpeed << 1 | dcDir; RFTxBuffer[(address + 1) * 2 + 1] = dcSpeed*3/4; } void setControllerLights() { //Right state lights show which individual module to control switch (controllerState[1]) { case 0: digitalWrite(rightStateLight0, LOW); digitalWrite(rightStateLight1, LOW); break; case 1: digitalWrite(rightStateLight0, HIGH);
  • 67. 67 digitalWrite(rightStateLight1, LOW); break; case 2: digitalWrite(rightStateLight0, LOW); digitalWrite(rightStateLight1, HIGH); break; case 3: digitalWrite(rightStateLight0, HIGH); digitalWrite(rightStateLight1, HIGH); break; default: controllerState[1] = 0; setControllerLights(); break; } //Left state is main showing Automatic, Manual (Configuration), and single module control switch (controllerState[0]) { case 0: analogWrite(leftStateLight, 0); //Single Module break; case 1: analogWrite(leftStateLight, 50); //Manual break; case 2: analogWrite(leftStateLight, 255); //Automatic break; default: controllerState[0] = 0; setControllerLights(); break; } } void getJoyStates() { joyState[0] = analogRead(A0); joyState[1] = analogRead(A1); joyState[2] = digitalRead(joyRightZ); joyState[3] = analogRead(A2); joyState[4] = analogRead(A3); joyState[5] = digitalRead(joyLeftZ); #ifdef JST_DEBUG printf("Joystick States: "); for (int i = 0; i < 6; i++) { printf("%d ", joyState[i]); } printf("n"); #endif
  • 68. 68 //debounce switches if (joyState[2] == 0 || joyState[5] == 0) { if (joyState[2] == 0) { controllerState[0] = (controllerState[0] + 1) % 3; } else { controllerState[1] = (controllerState[1] + 1) % 4; } setControllerLights(); while (joyState[2] == 0 || joyState[5] == 0) { joyState[2] = digitalRead(joyRightZ); joyState[5] = digitalRead(joyLeftZ); } delay(50); } } void setup(void) { // // Print preamble // Serial.begin(BAUD); printf_begin(); printf("Project: Low-Cost Reconfigurable Modular Robotsn"); printf("Code: Master Transmittern"); printf("Filename: src_master.inon"); printf("By: Tim Boles, Chris Coffee, Justin Galvan, and Steve Groffnn"); // // Setup and configure rf radio // clearBuffer(RFTxBuffer, 0); clearBuffer(RFRxBuffer, 0); pinMode(leftStateLight, OUTPUT); pinMode(joyRightZ, INPUT); digitalWrite(joyRightZ, HIGH); pinMode(joyLeftZ, INPUT); digitalWrite(joyLeftZ, HIGH); pinMode(rightStateLight0, OUTPUT); pinMode(rightStateLight1, OUTPUT); radio.begin(); // optionally, reduce the payload size. seems to // improve reliability radio.setPayloadSize(BUFFERLENGTH);
  • 69. 69 // // Open pipes to other nodes for communication // // Open 'our' pipe for writing // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1, pipes[1]); radio.powerUp() ; radio.startListening(); // Dump the configuration of the rf unit for debugging radio.printDetails(); for (int i = 0; i < 11; i++) { toModule(i, 512 * 13 / 1023, 0, 0, 0); } setControllerLights(); } void loop(void) { printf("state[0] = %d n state[1] = %dn", controllerState[0], controllerState[1] ); //clearBuffer(RFTxBuffer, 2); getJoyStates(); //For Single Module Control if (controllerState[0] == 0) { if (joyState[0] > 600) { toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 1, joyState[0] / 4); } if (joyState[0] < 400) { toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 0, 255 - joyState[0] / 4); } if (joyState[0] < 600 && joyState[0] > 400) { toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, 0, 0, 0); } if (joyState[3] < 400) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(controllerState[1] * 2 + 1, 6, 0, 1, 255 - joyState[3] / 4); } if (joyState[4] > 600) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } if (joyState[4] < 400) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } }
  • 70. 70 if (joyState[3] > 600) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(controllerState[1] * 2 + 1, 6, 0, 0, joyState[3] / 4); } if (joyState[4] > 600) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4); } if (joyState[4] < 400) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4); } } if (joyState[3] < 600 && joyState[3] > 400) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(controllerState[1] * 2 + 1, 6, 0, 0, 0); } if (joyState[4] > 600) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, 0); } if (joyState[4] < 400) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, 0, 0, 0); } } if (controllerState[1] == 3) { if (joyState[0] > 600) { toModule(1, joyState[1] * 13 / 1023, 0, 1, joyState[0] / 4); } if (joyState[0] < 400) { toModule(1, joyState[1] * 13 / 1023, 0, 0, 255 - joyState[0] / 4); } if (joyState[0] < 600 && joyState[0] > 400) { toModule(1, joyState[1] * 13 / 1023, 0, 0, 0); } if (joyState[3] < 400) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(2, 6, 0, 1, 255 - joyState[3] / 4); } if (joyState[4] > 600) { toModule(2, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } if (joyState[4] < 400) { toModule(2, 12 - joyState[4] * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } } if (joyState[3] > 600) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(2, 6, 0, 0, joyState[3] / 4); } if (joyState[4] > 600) { toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4); } if (joyState[4] < 400) {
  • 71. 71 toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, joyState[3] / 4); } } if (joyState[3] < 600 && joyState[3] > 400) { if (joyState[4] < 600 && joyState[4] > 400) { toModule(2, 6, 0, 0, 0); } if (joyState[4] > 600) { toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, 0); } if (joyState[4] < 400) { toModule(2, 12 - joyState[4] * 13 / 1023, 0, 0, 0); } } } } //For Manual control of module configurations if (controllerState[0] == 1) { if (controllerState[1] == 0) { //Car 0,1 are left wheels, 2,3 are right wheels if (joyState[0] > 600) { toModule(0, 1000 * 13 / 1023, 0, 1, joyState[0] / 4); toModule(1, 1000 * 13 / 1023, 0, 1, joyState[0] / 4); } if (joyState[0] < 400) { toModule(0, 1000 * 13 / 1023, 0, 0, 255 - joyState[0] / 4); toModule(1, 1000 * 13 / 1023, 0, 0, 255 - joyState[0] / 4); } if (joyState[0] < 600 && joyState[0] > 400) { toModule(0, 1000 * 13 / 1023, 0, 0, 0); toModule(1, 1000 * 13 / 1023, 0, 0, 0); } if (joyState[3] > 600) { toModule(2, 1000 * 13 / 1023, 0, 0, joyState[3] / 4); toModule(3, 1000 * 13 / 1023, 0, 0, joyState[3] / 4); } if (joyState[3] < 400) { toModule(2, 1000 * 13 / 1023, 0, 1, 255 - joyState[3] / 4); toModule(3, 1000 * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } if (joyState[3] < 600 && joyState[3] > 400) { toModule(2, 1000 * 13 / 1023, 0, 0, 0); toModule(3, 1000 * 13 / 1023, 0, 0, 0); } } if (controllerState[1] == 1) { //Snake/Oscillation motion if (joyState[0] > 600) { toModule(0, 512 * 13 / 1023, 0, 0, 0); toModule(1, 512 * 13 / 1023, 0, 0, 0);
  • 72. 72 toModule(2, 512 * 13 / 1023, 0, 0, 0); toModule(3, 512 * 13 / 1023, 0, 0, 0); toModule(4, 512 * 13 / 1023, 0, 0, 0); } if (joyState[3] < 400) { toModule(0, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); toModule(0, 512 * 13 / 1023, 0, 0, 0); toModule(1, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); toModule(0, 50 * 13 / 1023, 0, 0, 0); toModule(1, 512 * 13 / 1023, 0, 0, 0); toModule(2, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); while (joyState[3] < 400) { toModule(wave % 5, 512 * 13 / 1023, 0, 0, 0); toModule((wave + 1) % 5, 50 * 13 / 1023, 0, 0, 0); toModule((wave + 2) % 5, 512 * 13 / 1023, 0, 0, 0); toModule((wave + 3) % 5, 1000 * 13 / 1023, 0, 0, 0); toModule((wave + 4) % 5, 512 * 13 / 1023, 0, 0, 0); wave++; getJoyStates(); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); } } if (joyState[3] > 600) { toModule(4, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); toModule(4, 512 * 13 / 1023, 0, 0, 0); toModule(3, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); toModule(4, 50 * 13 / 1023, 0, 0, 0); toModule(3, 512 * 13 / 1023, 0, 0, 0);
  • 73. 73 toModule(2, 1000 * 13 / 1023, 0, 0, 0); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); while (joyState[3] > 600) { toModule((wave + 4) % 5, 512 * 13 / 1023, 0, 0, 0); toModule((wave + 3) % 5, 50 * 13 / 1023, 0, 0, 0); toModule((wave + 2) % 5, 512 * 13 / 1023, 0, 0, 0); toModule((wave + 1) % 5, 1000 * 13 / 1023, 0, 0, 0); toModule((wave + 0) % 5, 512 * 13 / 1023, 0, 0, 0); wave++; getJoyStates(); sendTxBuf(); sendTxBuf(); sendTxBuf(); delay(100); } } wave = 0; } if (controllerState[1] == 2) { //4 modules walking if (joyState[0] > 600) { toModule(0, 512 * 13 / 1023, 0, 1, joyState[0] / 4); toModule(1, 512 * 13 / 1023, 0, 1, joyState[0] / 4); } if (joyState[0] < 400) { toModule(0, 512 * 13 / 1023, 0, 0, 255 - joyState[0] / 4); toModule(1, 512 * 13 / 1023, 0, 0, 255 - joyState[0] / 4); } if (joyState[0] < 600 && joyState[0] > 400) { toModule(0, 512 * 13 / 1023, 0, 0, 0); toModule(1, 512 * 13 / 1023, 0, 0, 0); } if (joyState[3] > 600) { toModule(2, 512 * 13 / 1023, 0, 0, joyState[3] / 4); toModule(3, 512 * 13 / 1023, 0, 0, joyState[3] / 4); } if (joyState[3] < 400) { toModule(2, 512 * 13 / 1023, 0, 1, 255 - joyState[3] / 4); toModule(3, 512 * 13 / 1023, 0, 1, 255 - joyState[3] / 4); } if (joyState[3] < 600 && joyState[3] > 400) { toModule(2, 512 * 13 / 1023, 0, 0, 0); toModule(3, 512 * 13 / 1023, 0, 0, 0); } } } //For Auto control of modules
  • 74. 74 if (controllerState[0] == 2) { set = 0; if (joyState[0] > 600 || joyState[0] < 400) { set = 1; } if (joyState[1] < 600 && joyState[1] > 400) { toModule(controllerState[1] * 2, 6, set, 0, 0); } if (joyState[1] > 600) { toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, set, 0, 0); } if (joyState[1] < 400) { toModule(controllerState[1] * 2, joyState[1] * 13 / 1023, set, 0, 0); } set = 0; if (joyState[3] > 600 || joyState[3] < 400) { set = 1; } if (joyState[4] < 600 && joyState[4] > 400) { toModule(controllerState[1] * 2 + 1, 6, set, 0, 0); } if (joyState[4] > 600) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, set, 0, 0); } if (joyState[4] < 400) { toModule(controllerState[1] * 2 + 1, 12 - joyState[4] * 13 / 1023, set, 0, 0); } set = 0; } sendTxBuf(); /*if ( radio.available() ) { // Dump the payloads until we've gotten everything bool done = false; printf("Received: "); while (!done) { // Fetch the payload, and see if this was the last one. done = radio.read( &RFRxBuffer, BUFFERLENGTH ); } for (int j = 0; j < BUFFERLENGTH; j++) { printf("%02x ", RFRxBuffer[j]); } clearBuffer(RFRxBuffer, 2); printf("n");