Debugging 3001

From robotics

Overview:

1) Use an O-scope to check your pins.

2) Remove all print statements from your code once your done with them. They cause long delays that can affect time sensitive code such as PID.

3) Check what pins you are using and make sure they are not in use already and are configured for there intended use.

4) Make use of print statements in a smart manner.

Oscilloscope

Error creating thumbnail: File with dimensions greater than 12.5 MP
Test points on the board.

The first thing a staff member is likely to do is to connect an oscilloscope and check to see if a couple of signals are working. The corresponding image for test points can show you some helpful spots to probe for all components on the board. Taking the witch hat off of the scope probe allows for you to connect the o-scope to the board easily into either ports or any of the testing ports. If you do this however, make sure to place the witch hat back so other students can use the equipment.

If you do not know how to use an o-scope, please read the instructions here.

Pins to be careful of using

Below is a condensed list of some of the pins on the main processor. Some such as the SPI pins can't be used if working with SPI for things such as buttons or LEDS while other pins such as the analog pins should only be used if the pin is not in use. While there are others that you may not want to use depending on your code, these are some of the more common ones many students try to use to operate buttons or LEDs and encounter issues.

Port Pin Purpose
A 0 - 7 Analog Pins (4 - 7 safe to use with the breakouts)
B 4 SPI SS
B 5 SPI MOSI
B 6 SPI MISO
B 7 SPI Clock
D 0 - 3 Coprocessor and USB communications

SPI

SPI clock example 3001
SPI Ports
Relevant SPI ports:
PB7 - Clock
PB6 - MISO
PB5 - MOSI
PB4 - SS (Active low)

If your SPI bus is not working, first check the clock on PB7 and it should look something like the shown image. 8 bits are being transmitted on the clock edges to devices such as the DAC. If there is no signal, check your registers as something is likely wrong. If you see the clock but still have issues, next check the corresponding data line to make sure that is working as well as the chip selects on all devices. Checking all device chip selects makes sure you are not having devices interfere with one another on the one data bus.

If you are still having issues see go to this section if you have any of the ports connected to anything such as LEDs or buttons, otherwise proceed to here.

DAC

DAC locked up? Power cycle to fix. This includes disconnecting the USB and power supply. If it happens often you can add a 5k resistor between VCC and the Slave select pin.

The DAC is an active low SPI device. Due to this the DAC can lock up when sending code to the Main processor. The ISP programmer uses the SPI pins to to program the AVR chip. When being programmed the AVR chip's pins go low including the DAC's slave select pin. This allows the AVR code to get to the DAC and sometimes locks it up. If it happens often you can add a 5k resistor between VCC and the Slave select pin. This should reduce this issue.

Analog, Digital and Servo Ports

The easiest way to check the ports is to remove your device and insert probe into the corresponding signal pin and follow the Oscilloscope section.


Analog ports 4 - 7 go directly to pins 4 - 7 on Port A.

Servo ports 0 - 5 go to the coprocessor ports PD2 - 7 and servo ports 6 -7 go to coprocessor ports PB0 - 1. NOTE: Port B pints is mislabeled on the coprocessor, they are located at the bottom of the chip.

For all digital pins just connect the probe to your pins as needed.

If you have Connections to Ports

If you are using the buttons, switches, LEDs or any external sensors please refer to the Pins to be careful of using section and the Oscilloscope section to make sure there is nothing else on that line. Also check the data sheet for additional features you may be using that can affect it, however the oscilloscope would likely reveal any issues quickly.

Print Statements

The board does not have a JTAG interface so you are not able to use debugging features that you may be used to from classes such as ECE 2049. You will therefore have to make good use of print statement to print out variables and register values. When you are done with prints, it is important to remove them so they do not slow down your program!

Printing Useful Information

Printing something useless vs. useful

When printing out data, it is important to print data that is useful to you, your partners and staff members if you ask for help, see the image for reference. Printing data in this manner allows for anyone to quickly look at the screen and see what is going on, the "---" helps to seperate separate loops and aligning the numbers allows for you to quickly look down the list to see everything.

Printing Registers

Sometimes it is helpful to print out registers to make sure you got them set correctly. To do this, you can simply print the hex value using sprintf() such as

sprintf(buffer, "%#04x", ADCSRA);

to print out the hexadecimal value of the register. This will give out a result such as

0x87

representing the value of the ADCSRA register. An important thing to note is that you need to use 4 characters to display a byte as the "0x" counts towards the 4 characters printing (2 for 0x, 2 for the byte).

Dummy Data

Often times you will be pulling in data from various sensors and doing some math to do something such as calculate calculating the voltage level of the potentiometer. For equations such as this, you should call your function with a static value that you know what the return value should be so you can see what happens. Once you get the function to return the correct value, try another value or two to make sure you have multiple cases working and then go back to your sensor data.

Datatype Mismatch

A datatype mismatch is one of the most common problems that is created by not being careful with your data. It is caused by having two variables of different and assigning one to the other, typically with some math involved. A simple example follows where a buffer overflow is created and causes unexpected results. While this example is obvious, many are not and it is safest to create temporary variables of the same datatype than to assign datatypes that differ and is better than casting.

Whenever you have a problem with results not making sense, try making all the datatypes the same either with temporaries or making the variables all the same.

Datatype mismatch results
int main(){
  unsigned long long llType = 18446744073709551615;
  printf("%llu\n\r", llType);
  unsigned int iType = llType /  3;
  printf("%d\n\r", iType); //Should give 6148914691236517205
  char  cType = iType + 9;
  printf("%d\n\r", cType); //Should give 6148914691236517214

  return 0;
}


Race Conditions

A hard problem to track down but is uncommon in 3001 is a race condition, which is when different threads try to access shared data at the same time. As you are not creating multi-threaded applications the only issue you may run into is with ISRs and your main code. When accessing data that your ISRs operate on, such as your millisecond counter, you should copy the data into the local function and define the variable as extern. Ideally you should also disable interrupts and/or create semaphoes while accessing shared data, however in this application it should not be needed.

Finding a Coding Problem

Often times you will put your print statements at the end of your code before you re-loop and a value is incorrect. One way to find the error is to remove (or comment out) all print statements to ease debugging. Next, go to whatever function is having problems and start doing the following:

1) Put a print after every spot the variable is modified.

2) Run the code and find the variable becomes incorrect.

3) If doing multiple mathematical steps at once, split the line into one at a time and add more print statements.

4) Check datatypes and recheck how any helper functions works such as the sin() function in math.h work which is expecting a radian value, not degrees.

5) Check static test data that you know what the value should be (eliminate dynamic data such as sensor data).

Board Thinks it's a Mouse

Every time 3001 is offered at least one group has a problem where there board is detected as a mouse. If it is on a lab computer you can try another PC, but you will likely need to talk to Joe as he has administrator access on the PCs. If it is on your own laptop, look here or search Google for "Disable serial mice windows X" where X is your version of Windows.

You can also hold the reset button down on the AVR-644p while inserting the usb cord to the pc and wait about 10 seconds. The characters sent by your program are telling your PC it is a mouse. By holding down the button the characters will not be sent.

SVN Lock or errors

Sometimes your projects .svn files can be locked or corrupt creating errors while trying to connect, checkout, or commit code. The easiest way to fix this issue is to remove the .svn folder found in your project. 1. To show hidden files simply type "show hidden" into the windows search bar. Select the option for "show hidden files and folders". Once the "folder options" window appears, simply check show hidden files and folders. Then click apply. 2. Close eclipse. 3. Delete the .svn folder. 4. Open eclipse, delete unresponsive repository locations, and attempt to connect, checkout, or commit code.

Windows 8 and 10 compilation error 0xC0000142

This error can be fixed with the modification of a file. Basically unzip this file and copy mysys-1.0.dll file into "c:/winavr-2xxxx/util/bins". You do want to replace the file that is there.

SetServo.c errors

The forward / for windows need to be replaced with a \ for mac and linux.


eclipse nested folders creating register errors

If your file is highlighting AVR registers as an error even when they are correct: Use the following include to fix it.

#include <avr/iom644p.h>