Skip to content

jcondor98/ammc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AVR Multi Motor Control

This repo contains the entire codebase and documentation for the bachelor degree apprenticeship, which is supervised by Prof. Giorgio Grisetti and Drs. Barbara Bazzana.

Overview

The project consists in a multi-motor control system, structured in a master-slave fashion. Each DC motor is individually handled by a dedicated standalone AVR controller. The Atmel AT2560 is used for every (master or slave) microcontroller.

The master controller must:

  • Communicate with the slaves (i.e. controllers handling individual motors) via the I2C protocol
  • Communicate with a PC via the serial (over USB) protocol

The end user will interface just the master controller, using a TUI program which runs under POSIX-compliant OSes.

Features

  • Text-based client application for POSIX environments
  • Master and Slave(s) controller firmware
  • Fully binary Client-Master communication protocol on top of the serial interface
  • Fully binary Master-Slave communication protocol on top of the I2C interface
  • Up to 126 DC motors (limited by 7-bit I2C Slave addressing, 0x00 is reserved)
  • Ability to get and set the DC motors speed, individually
  • Software defined PID controller embedded in each Slave controller

Documentation

An overview of the project is given in this Markdown document.

Documentation generated with doxygen for the source code and the programming API can be found here.

The client is documented by the man page ammc(1).

Professor Reference

Quoting from Prof. Grisetti's repository:

[...]

  1. Arduino TWI communication ---> [x2] [C98] Use two (or more arduino), one configured as master the other ones as slaves Implement an interrupt based interaction protocol on i2c [http://www.chrisherring.net/all/tutorial-interrupt-driven-twi-interface-for-avr-part1/. The protocol should contain the following messages:

    Direction Command Description
    master -> all sample the slaves sample all digital inputs and puts them in a struct
    master -> slave[i] ->master get the slave number i sends the sampled digital inputs to the master
    master -> slave[i] set the master sends to the slave i the desired output pin configuration in an internal struct, "without" applying it
    master -> all apply the slaves apply the saved pin status to the outputs

    The slaves react only to interrupts. they are in halt status. The master offers an interface to the host (PC) program to control the slaves, via UART. All protocols are binary, packet based

  2. Arduino motor controller [x1] [C98] If you have a DC motor with encoder, implement a closed loop motor servo using a PID controller The arduino reads the encoder, and issues a PWM, so that the speed of the motor measured by the encoder matches a desired speed set by the user. The Host program allows to set a speed via uart, and the program on the arduino periodically sends back the status (pwm, encoder position, desired encoder speed and measured encoder speed)

  3. Arduino multi motor control [x4] [C98] integrate project 1 and project 2. Each slave controls a motor and communicates via i2c to the master that provides a unified interface. The event loop on the slaves is synchronized with the "apply" command.

[...]

Installation

The entire project uses the GNU Make build system. Client, Master and Slave programs' codebases are separated from each others.

A list of make recipes is given below:

# Make client executables and master and slave .elf binaries
make

# Compile and link the client-side executable
make client

# Install the -ALREADY COMPILED- client-side executable
sudo make install

# Generate man page (requires pandoc)
make docs

# Install man page (pregenerated in the repo)
sudo make install-docs

# Compile and link master .elf binary
make master

# Compile and link slave .elf binary
make slave

# Encode the master .elf binary into a .hex file and flash it into the AVR
make master-flash

# Encode the slave .elf binary into a .hex file and flash it into the AVR
make slave-flash

Specification

Client-Master communication

The Client-Master communication protocol is binary, packet-based and built on top of the Serial-over-USB protocol offered by the AT2560 board. Each packet has a variable length and its integrity is checked with a trailing CRC-8 checksum.

Packet Header

The header is composed of the following fields:

Field Size (bits) Description
id 8 Packet ID
type 8 Packet type
selector 8 Selector for DC motors. Also used to store error codes in NAK packets
size 8 Total packet size, including header and checksum

type can have the following values:

Type Actual value Description
COM_TYPE_NULL 0x00 Reserved, never use
COM_TYPE_HND 0x01 Handshake
COM_TYPE_ACK 0x02 Acknowledgement
COM_TYPE_NAK 0x03 Communication error
COM_TYPE_ECHO 0x04 [DEBUG] Echo between Client and Master
COM_TYPE_PING 0x05 Ping a slave controller
COM_TYPE_GET_SPEED 0x06 Get the current speed for a DC motor
COM_TYPE_SET_SPEED 0x07 Set (and apply) the speed for a DC motor
COM_TYPE_APPLY 0x08 Tell all the slaves to apply the previously set speeds
COM_TYPE_DAT 0x09 Primarily used for responses from the AVR device
COM_TYPE_SET_SLAVE_ADDR 0x0A Set new TWI address for a slave controller
COM_TYPE_LIMIT 0x0B Used for sanity checks - Must have highest value

Acknowledgements

A communication endpoint must wait for an acknowledgement message from the counterpart once it sent a packet in order to send a new one. ACK and NAK packets do not bring any data.

When a packet arrives, it is checked for integrity and sanity. If it is sane, then an ACK packet is sent; if not, then a NAK packet is sent. ACK and NAK packets are simply discarded if corrupted in some way.

A NAK packet uses the 'selector' field to send the error code describing what happened on its side to the other endpoint. Error codes can be found in include/common/communication.h.

Controlling DC motors' speed

The master controller offers an upper-level, command-based API to handle the DC motors:

Client command Description
ping <motor-id> Ping a slave controller
get-speed <motor_id> Get the speed of a DC motor
set-speed <motor_id>=<speed> Set the speed of a DC motor
apply Apply the previously set speeds to all the DC motors

Further informations can be found in the man page or by issuing the help command to the client shell.

NOTE: The sample command has been removed from the specification, since the effective speed is periodically sampled by each Slave, as needed by the embedded PID controller.

Master-Slave communication

Master and slaves communicate to each other using the I2C/TWI protocol. The implementation had been realized from scratch and also offers broadcasting capabilities from master to slaves, based on the 0x00 built-in broadcasting address.

The communication layer on top of the I2C protocol is completely binary and interrupt-driven.

Communication frame

The I2C communication frame is composed of a leading byte representing the code of the command to be executed by the slave controller, and a variable size trailing argument. The commands are listed below:

Command Code Description
DC_MOTOR_CMD_GET 0x00 Get the sampled motor speed
DC_MOTOR_CMD_SET 0x01 Set a new target speed
DC_MOTOR_CMD_APPLY 0x02 Apply the previously set speed
TWI_CMD_ECHO 0x03 Echo a byte back to master (debug)
TWI_CMD_SET_ADDR 0x04 Change the current I2C address (i.e. motor id)

Notes

The doxygen custom CSS files is taken from jothepro, here. It is released under the MIT license.

About

AVR Multi Motor Control

Topics

Resources

Stars

Watchers

Forks