What be CAN? [understanding life]
Updated: Mar 8, 2020
This post is about the CAN interface and what CAN even is before we start going on this adventure of creating a CAN Bus using the CANBridge to control all of our many many many motors.
step one: traditional control
So first, let's talk about traditional robotics control systems. Traditional control systems involved one central controller with a number of "ports" think of this like the Arduino where you have digital PIN_OUTS. You connect peripherals like motors controllers to PIN_OUTS like the right leg shoulder motor is on PIN_1, and you don't really control the motor controller you send a signal to PIN_1 which happens to be compatible with the motor controller connected to PIN_1. You KNOW what you're controlling by virtue of the fact that it's plugged into PIN_1 but other than that the board has no idea what it's controlling on PIN_1 or if anything is even connected to PIN_1. It's just sending signals to the pin. In this type of control, each peripheral gets its own port, and the controller (Arduino or similar) the code controls the port and the port is outputting compatible signals to the peripherals. I'll refer to this as port-based-control.
In the case of the Arduino Digital Pins, the signal sent by the port-based control system is a PWM signal. PWM stands for pulse-width-modulation. It is a square wave.
In this type of signal. The signal has a set period, or set cycle-time. And it is either a HIGH value or a LOW value for whatever percent of the cycle time. The percent of the cycle time that the signal is HIGH is called the duty cycle and that's actually the piece of information sent. The time of the duty cycle in milliseconds (usually a value between 1000 and 2000 ms with 1500ms being center) is the signal sent by the controller and then read by the peripheral. The peripheral only takes in this millisecond number, and then on its own decides what to do wether that's move a servo to a position or move a motor a certain speed.
The problem with PWM is PWM is an open-loop control system. The controller simply sends a signal and gets no feedback whatsoever. It can't get feed back, it's physically incapable because the only thing PWM libraries are setup to send and receive is the length of the duty cycle. So how this is usually solved is by wiring a sensor, like a motor encoder, directly to the controller (the Arduino or something) to give feedback to the controller to close the loop. The system then looks like controller-->pwm_interface-->motor_controller-->actuator-->affects_environment-->motor_spins_with_load-->encoder_reads_spin-->sends_back_to_controller-->controller_processes_feedback.
Now this does work but of course there's a lot of wiring that needs to happen here, the system gets complicated and all the processing must be done on the micro-controller so that clogs the system memory and etc especially in complicated systems. So is there a better way?
CANBus: a nice thing
Yes, CAN Bus, a nice thing. CAN virtually solves most of the problems that we run into trying to do feedback-control with PWM. CAN Bus is a form of standardized, robust, network, that allows for feed-back control in complex systems. Okay, what the hell does that even mean? Let's break it down step-by-step.
STEP A: NETWORKING
The first step to understanding CAN is understanding the CAN Network. CAN is a network-based control system meaning that it's very different from the port-based control that robotics was used to for so long. CAN is very sightly like the internet for robots if you want to think of it that way. Imaging the CAN Network as an internet with information on it, and your controller as a hub/server that controls this network. The motor controllers and peripheral devices all connect to this network and then things happen. The motor controllers (for example), either request/send information about their states and what they're supposed to do or they wait for the controller to issue a command. If any device, controller or anything, publishes a message to the network, it goes to ALL the devices on the network. But how the device knows it is meant for itself or not, is that CAN messages are addressed to specific devices.
So imagine 5 motor controllers 01, 02, 03, 04, and 05 connected to a CAN Network. The computer takes in information and decides motor 05 should move at 50% speed. So the CAN network now gets a message saying "motor 05 move at 50% speed." Every device on the network receives it, but only motor 05 moves because the message only is addressed to motor 05. It's like if your boss is assigning tasks at a board meeting. "Adi you're going to email Chris about this 3D print right?" Adi will email Chris, and the give the boss feedback saying "yes I have emailed him." But this conversation happens in an open room where everyone in the room can hear the message, they just ignore it because it doesn't pertain to them. That's the CAN Network in a nutshell.
STEP B: THE CAN MESSAGE
The next step is CAN is robust. And before we talk about the how and the why and the what even... this is a great opportunity to describe what the CAN message looks like, how it is transmitted and wired. We're going to take the example of FRC CAN which is the CAN we will be using for the scout project.
The above table is an example of a CAN message. A CAN message is simply a string on bits like above 00010000000101000011010, like that where the bits are grouped into pieces of information to transmit data. The FRC CAN protocol involves 29 bits, and each can be 0 or 1. The numerical value of a group of bits is the information being sent to the network.
Let's Break Down this Example:
Device Type: Is a 5-bit number that tells the network what type of device we are commanding. In this case 00010 means "motor controller," so when this packet is sent to the network and read, the first thing is only motor controllers will pay attention to this signal.
Manufacturer Code: Is a 8-bit numeric that tells the network which manufacturer we should be looking for. This helps further eliminate the controllers on the network we are looking for. Now only "Jaguar" made motor controllers are listening.
API Class: This is a 6-bit value that tells the motor controller what type of command to be expecting, the class of the command from "Speed Control" to "Velocity Control" and so much more. It preps the motor controller, hey you're about to get this kind of command.
Index: This is the actual command coming to the motor controller wether that's a velocity set point, position set point, zero, reset, enable, disable, whatever. This is the value of the command itself. It is a 4-bit value. It's telling the motor "we're going to send you this soon."
Device Number: Finally, we get the 6-bit numeric called Device Number this is also referred to as the CAN_ID of the device. This is a unique number assigned to each CAN device on a network (kind of like an IP address on the internet). This now tells the network exactly which device to command.
Now you're probably wondering why if each device has a unique ID, what the point of the manufacturer code and the device type is. Well, that's because really, each device doesn't need to have a unique ID in this case. All motor controllers may need a unique ID but you could have a motor controller with CAN_ID 0 and a processor node with CAN_ID 0. What this would mean is the controller is the "0th controller" and the node is the "0th computer" in plain English. Think of it like that. This allows smaller CAN_IDs, we don't need to go through each and every thing in the network and make sure the IDs are different. We just need to go through the motor controllers. This helps workflow and can be noticed when trying to setup a CAN system.
STEP C: How is the CAN Message Transmitted, Physically?
The question now becomes, how does the CAN message get transmitted, how do I wire a CAN system, and why does it get transmitted that way. So the CAN system has two connection wires yes, that's it, two connection wires. There's a CANH (high) and a CANL (low) wire, in FRC this is the green and yellow in whatever order it doesn't matter at the moment one is high and one is low.
The two CAN wires are nominally at ~2.5V each, when a signal goes through, the CANH jumps to ~3.5V and the CANL drops to ~1.5V and Vcanh - Vcanl = Vdiff for the CAN system. Therefore, CAN is what we call differential. It takes the difference between the high and the low wires. If Vdiff > 0.9V the CAN Bus is in the dominant state, and if it's <0.5V the CAN Bus is in the recessive state.
The entire CAN BUS transmits the SAME signal at the SAME time. The diagram below best describes how the HIGH/LOW of CAN Bus transmits data in the form of bits for an entire CAN Message.
If the bus is in the dominant state we are transmitting a "0" bit if the bus is in a recessive state the bus is transmitting a "1" bit. But there's more questions right? Like how do we know when we are starting a message, how do we know when we are ending a message, and etc. How do multiple messages get sent over CAN at the same time?
The diagram above shows a true full-form CAN message. It's unclear if the FRC protocol runs the same way, but the 29bit integer we described above is actually the CAN-ID extended identified. The data, as you can see, comes after and at the beginning and end of the message there are SOF and EOF commands that tell the bus a command is starting or ending. Once the SOF command is received all the nodes on the bus start the same clock, and the clock ends when the EOF command is received, the message is then decoded.
Now how do multiple messages get sent over CAN at the same time? They don't. Is the Rea answer. The bus is a single two-wire interface there's no-way that we can send more than one message. Instead, each message has a priority level. Messages with the highest priority are sent first, and then the messages with lower priority are sent after. YES this causes some messages to be delayed but usually, due to the speed of CAN transmission, this isn't usually an issue. But because of this, CAN is also not really real-time. CAN can usually transmit around 125 kbit/s. Which is pretty fast though.
So CAN messages that are transmitted to the network go to a CAN buffer before they're transmitted. The buffer takes the messages and transmits them to the network ONE AT A TIME based on two things (1) the timestamp of the message, and (2) the priority of the message. What this means is the messages sent first are published first and if messages are sent at the same time the highest priority messages are sent first. But on the bus itself, there can be ONLY ONE message at any time. Remember CAN has no ability to do point-to-point communication. All the communication on CAN is the same, every node receives every message, and they all receive them at the same time.
So CAN bus can make our lives easier in many ways. It makes wiring easier, it makes us not have to worry about ports and things like that. There are other advantages to CAN Bus as well. Since CAN is differential, it's resistant to spikes in voltage and current and things like that, making it a very robust form of communication.
NOTE: Some of these images are not my own. Full credit to the people who took them.