Gas station without pumps

2017 November 15

Events and Services Framework ported

Filed under: Robotics — gasstationwithoutpumps @ 23:11
Tags: ,

I’ve ported the Events and Services Framework from Mechatronics to the Teensyduino environment.  I copied (with slight modifications) the code that I wrote for Lab 0 (the roach lab) to debounce buttons and detect changes in light level, and it worked fine.  It took me a little while to convince myself that everything was working, because the light I’m working by is a somewhat dim LED bulb, and I was seeing very little change in the phototransistor output when I put my hand over the sensor.  I had to hook up my oscilloscope to convince myself that the values I was seeing were correct—there was little change because the phototransistor was not very sensitive to the light I was working with.

I also ended up throwing away some of the precision of the analog-to-digital converter so that the filter constants would work out to avoid overflow.  Since I won’t actually be using these filters in the final robot (I’ll be doing synchronous detection for the tape sensors, not filters that adapt to background light), I won’t have the same problems in the robot.

So I’m now ready to start writing my software, but that will have to wait until after class tomorrow, as I have some sleep to catch up on.

2017 November 8

Starting to port the Events and Services Framework to Teensy boards

Filed under: Uncategorized — gasstationwithoutpumps @ 23:23
Tags: , , ,

Because I want to work at home with boards that I own, I need to port the Events and Services framework used in the Mechatronics class to the Teensy LC or Teensy 3.1 board.  The first thing to do is to identify what resources are used by the Teensyduino framework, and so inaccessible to me (except through their API).

The ES framework itself has only one interrupt routine, in ES_Timers.c, which runs on a millisecond tick, updating FreeRunningTimer and checking to see whether any of the ES_Timers have just timed out. While I would have loved to do this with the SysTick timer on the Teensy boards, Teensyduino uses that its own millisecond timer (accessible through millis()).  So I’ll probably have to use the IntervalTimer interface, which will use up one of the PIT (programmable interrupt timer resources).

Because I’ll be doing hardware pwm on selected pins, not software pwm, I don’t need to port the pwm code from the Uno32 library.  I will need timer resources for hardware pwm, which means using pins that have pwm support.  Different pins use different timers for the pwm, and the table at https://www.pjrc.com/teensy/td_pulse.html provides the mapping:

Teensy 3.2
Teensy 3.1
FTM0 5, 6, 9, 10, 20, 21, 22, 23 488.28 Hz
FTM1 3, 4 488.28 Hz
FTM2 25, 32 488.28 Hz
Teensy LC FTM0 6, 9, 10, 20, 22, 23 488.28 Hz
FTM1 16, 17 488.28 Hz
FTM2 3, 4 488.28 Hz

(They provide the mapping for other Teensy boards also, but I will only use LC and 3.1/3.2 boards on this project.) If I just use two PWM channels, then pins 3 and 4 would be a good choice on either chip, as few other uses conflict with those pins and they share a timer.  If I need more than 2 PWM channels, then pins 6, 9, 10, 20, 22, and 23 share FTM0 on both chips. Three of those channels are also A-to-D channels and pin 20 is SCK1 (the second SPI interface clock).  I’m planning to use pints 11, 12, and 13 for the SPI interface, plus one other digital pin for the chip select, so the conflicts on the PWM pins are probably irrelevant.

I don’t like the default PWM frequency of 488.28 Hz, though, and so will be changing the PWM resolution and frequency to get a PWM frequency above the audible range (the MAX14870 H-bridges had no trouble handling up to 50kHz).  Using an 10-bit resolution with a clock speed of 48MHz (Teensy LC) would give me a PWM frequency of 46875Hz and  with a clock speed of 72MHz (Teensy 3.1) 35156.25Hz (the code does some prescaling).  These look like good frequencies to request.

The code provided for the Uno supports RC servos with another timer.  In the Teensyduino library there are two different servo implementations: Servo and PWMServo.  PWMServo uses the same PWM hardware that the pwm library uses, but at a 50Hz PWM frequency.  If I use that library, it will be important to cluster the servo pins on to one of the FTM timers and the pwm pins onto a different timer.  The Servo library uses the LPTM timer on the Teensy LC and the PDB timer on the Teensy 3.1/3.2, which does not conflict with other uses, but the servo timing is subject to glitching, especially if interrupts are ever disabled in the code.

The Uno32 board is set up to read analog-to-digital values continuously so that reading the data can be a non-blocking operation that just grabs the latest value without waiting for a new conversion.  For my first version of the port, I’ll just use analogRead to read pins, but if that turns out to be too slow (which it might), I’ll change to using the analog reading used by PteroDAQ. One oddity of the ES framework is that the battery-check code is built into the analog-to-digital conversion code, and the processor put to sleep if the battery is low.  I suppose this was done so that filtering of the battery voltage could be done in the interrupt routine that samples all the ADC channels.  It seems like a worthwhile thing to shut everything down if the battery gets too low, so I might decide  to do something like theADC library.  The Teensy boards don’t have an interface for cycling through the channels the way the Uno32 appears to, so I would probably have to set up a rather different interface for this.  This looks like the biggest difficulty in porting the framework—it might be better to set up a battery monitor that is not embedded so deeply in the code, perhaps having a battery-check event checker that is automatically polled.

The provided timers.c package gives access to another set of millisecond timers, which can be polled.  This library does not seem very useful—if I want to know the time, I can call millis() and if I want to poll whether enough time has elapsed, I can compare millis() to a computed stop time.  It does not seem worthwhile to use up another timer just for millisecond resolution.

I’m not planning to use a stepper motor, so I won’t port the Stepper routines (which we had to modify as a homework exercise).  If I were to port these routines, I’d probably use up another IntervalTimer (which exhausts them for the Teensy LC).

The serial.c code uses a UART interrupt to send or receive over the USB port, but the Teensyduino enviroment includes Serial, so all I would need to do is to

#define printf Serial.printf

and there is no need to port serial.

So far, it looks like the partial port that I’m planning (porting the ES framework but not the peripherals) looks very straightforward, other than the battery voltage monitor.  I might skip that in the first port, and add it back in later.

%d bloggers like this: