Prototype Status Report

Today I finished drafting a prototype status report, including various diagrams and schematics, and posted it on the group blog for the new Senior Design group on Blackboard.  First version I posted (1.0) had an error (extra resistor), fixed it in the next version (1.1).  Also found a discrepancy between intended schematic and actual board – a missing resistor on the board.  Fixed that.  Also found and fixed a couple of problems on the main board that happened when I did my last round of tests a few weeks ago.   One of the battery clips had come apart, and another one had become disconnected from the board.  Re-soldered those.  Also tried some heat-shrink tubing with my new hot-air gun.  Reassembled and tested.  Impact detection working again.

Figures in report:

Figure 1.  Prototype assembly - high level block diagram

Figure 1. Prototype assembly – high level block diagram.

Fig. 2:  Prototype HW photo.

Fig. 2: Prototype HW photo.

Fig. 3: Schematic of LCD/PB mini-board.

Fig. 3: Schematic of LCD/PB mini-board.

Fig. 4: Schematic of main board.

Fig. 4: Schematic of main board.

Fig. 5: Inter-module dependencies.

Fig. 5: Inter-module dependencies.

Fig. 6: Layered view of software.

Fig. 6: Layered view of software.

Senior Recruiting

Now recruiting students for the Senior Design team this Fall.  Here is the slide about the project shown to the students:

PowerPoint slide advertising Turf-Tec project

PowerPoint slide advertising Turf-Tec project

The slide includes a few new photographs taken recently:

Current appearance of prototype electronics box.

Current appearance of prototype electronics box. Note: LCD display has some glitches and needs to be replaced.

The G-max is “0” because I wasn’t able to take a reading the other day because the broken lead to the BNC connector still needs to be re-soldered (that got interrupted by the burned-table incident).

Photo of interior of current electronics box

Photo of interior of current electronics box

Complete current impact test prototype

Complete current impact tester prototype.

Battery Display, More GPS Tests

Add a two 100Kohm resistor voltage divider to feed the battery voltage to analog pin 2 (after dividing by 2), and now the battery-voltage-level indicator seems to be working.

Took the unit to the park to try to get some readings at different GPS coordinates, but unfortunately the plunger toppled over at one point, pulling the prototype to the ground, and pulling a couple of wires loose.  Re-soldering now.

In the meantime, here are the three data records we took at one location (three impact tests at locations about a foot apart from each other):

DAY TIME GMAX LONGITUDE LATITUDE
8/13/2012 9:09:14 PM 82 0 0
8/13/2012 9:10:08 PM 75 30.59375381 -84.58752441
8/13/2012 9:10:39 PM 65 30.59314346 -84.58673859

Looks like the coordinates blanked out there briefly when we were taking the first measurement… 😦

The green arrow below shows the location of the first reading.  Actually though, we were in the northwest corner of the park.

Reported location of 1st reading at park (incorrect)

Green arrow at center shows reported location of 1st reading at park (incorrect)

And here is the measured 2nd location – even farther off.

2nd GPS reading at park - even worse

2nd GPS reading at park – even worse.  The GPS thinks we’re down in the ravine.

Seems like we really should be doing some kind of location averaging.  And/or, displaying the inferred location on top of satellite/aerial imagery of the location, so that the user can see if it is correct.  This would take a vastly different system design though.

Code Cleanup

This weekend I worked on cleaning up & organizing the firmware code.  The present revision is 0.8 and it includes the following sections & subsections:

  Sec. 2: Sec. 3: Sec. 4:
  Module Macros/ Globals Functions
Subsec. # Name Constants in RAM & Procs.
1 String X
2 EEPROM X X
3 Serial X X
4 LEDs X X
5 Battery X X X
6 Timezone X X X
7 LCD X X X
8 GPS X X X
9 SD X X X
10 ADC X X
11 Accel X X X
12 Pushbut. X X X
13 Applic. X X X

Actually, subsection 4.13 is just called “section 5” (main application code).

Total compiled size is:   28,562 bytes.  (Less than before b/c I took out “refractory mode.”)

The only functional changes were changes in the behavior of the LEDs.  The green LED should now stay on a little longer, while parsing lines from the GPS and updating the LCD display.  And the red LED will no longer turn on for a couple of seconds hanging the unit in a “refractory mode” after the impact – that is no longer needed now that we have the HOLD application mode.

Oh, and I changed the battery-voltage display so that it will now be scaled properly when using a 9V battery with a 2:1 voltage divider.

The new firmware still needs to be tested.

Did a test; found that at some point the GPS module had reset its baud rate to 2,400.  Tried just running at 2,400 but this led to problems – we seemed unable to keep up with serial data (since now reading serial is taking up more of each second) and were getting garbled data.

Changed the rate back to 9,600 baud, but this experience where the baud rate resets itself during idle periods (which has happened twice now) drives home the lesson that we really need to automate this process.  We need a procedure that tries communicating at different baud rates until communication is established, then sets the baud rate to the desired 9,600 value.  Not sure if there is room to add this procedure though, until we have a larger processor.  I can try though.

In the meantime, I went outside to make sure I could still get satellites then brought the unit back in and did a test on our four test surfaces.  Here are the results:

Raw data:

Target DAY TIME GMAX LONGITUDE LATITUDE
(attach.) 8/12/2012 9:07:06 PM 504 30.59622574 -84.58686829
3 8/12/2012 9:08:11 PM 60 30.59604836 -84.58683014
3 8/12/2012 9:08:27 PM 72 30.59623337 -84.58695984
3 8/12/2012 9:08:40 PM 59 30.59628105 -84.58697510
1 8/12/2012 9:08:59 PM 57 30.59667969 -84.58744049
1 8/12/2012 9:09:11 PM 59 0.00000000 0.00000000
1 8/12/2012 9:09:21 PM 51 0.00000000 0.00000000
2 8/12/2012 9:09:40 PM 54 30.59657860 -84.58721161
2 8/12/2012 9:10:01 PM 57 30.59684372 -84.58746338
2 8/12/2012 9:10:11 PM 56 30.59691238 -84.58749390
4 8/12/2012 9:10:47 PM 53 30.59631538 -84.58715057
4 8/12/2012 9:10:59 PM 52 30.59635162 -84.58728027
4 8/12/2012 9:11:12 PM 57 30.59642220 -84.58755493

Since I was indoors, the GPS went out for a couple of readings…

Summary & analysis:

Average Clegg   Discrep.
Target Gmax average Discrep. %
1 55.7 59.2 -3.5 -6.0%
2 55.7 51.6 4.1 7.9%
3 63.7 89.0 -25.3 -28.5%
4 54.0 50.8 3.3 6.4%
AVG 57.3 62.6 -5.4 -5.0%

On average, we are reading -5% below the Clegg.  This is as opposed to the last test where we were reading +8.5% above the Clegg on average.

The target that is the farthest off is target 3 – its properties might have changed over time since John tested it.

Since this reading is so far off, it would probably be a good idea for me to look at the signal from target 3 on the scope to make sure that the software is really capturing the true peak of the pulse.

I checked the variability in the GPS coordinates, the average coordinate is a house off (at our neighbor’s house), and the farthest discrepancies from the mean are 170 feet further north and 93 feet east of that point.  Sometime later, I should do a test where I take a bunch of coordinates outdoors at a place with a good sky view, and see where they all are…

For reference, this is how the GPS coordinates jumped around over those tests…  The track starts on the right.

Measured GPS coords at home

Measured GPS coords at home

 

Looking Forward

John and I met today and discussed major goals for a new student team this Fall:

  • Build a revised prototype of the electronics box (possibly using the Arduino Mega 2560 for more memory) to incorporate the following features:
    • Transfer of stored files to PC via USB cable.  (Also needs PC-side app support.)
    • New, more reliable, lighter, higher-capacity (if possible) rechargeable battery / plug-charging solution, including quotes @ price breaks.
  • Design a complete & detailed mechanical model of the contents of the electronics box, including the following (Hopefully we can get a couple of ME students to help with this.):
    • All printed circuit boards & modules in system
    • Mount points for boards / any needed spacers / screw or bolt holes / fasteners.
    • All cables and cable connectors.
    • All components on boards.
    • Holes for panel-mount or peek-through connectors/sockets
    • LCD window
    • Bill of materials for any off-the-shelf mechanical components (box, screws, etc.)
  • In VERY CLOSE cooperation with the box’s mechanical designers, the EEs can work on a new PCB layout, including:
    • All needed hardware from selected Arduino board (perhaps the Mega 2560)
    • All needed hardware from the GPS/datalogger shield
    • Suitable mount points for pushbuttons, LEDs, connectors for USB & BNC cables and ribbon cable to LCD panel.
    • Mounting holes for the board itself.
    • Detailed electronic bill of materials, including source, exact part #, quoted prices @ several price breaks (e.g. 10/100), including for all connectors and cables (or cable assemblies), and for LEDs and pushbuttons and LCD panel.

Meanwhile, some smaller tasks I can work on in the meantime (next couple of weeks):

  • Maybe wire up battery-level pin to current batteries so can do a more representative preliminary test of that feature.  (Also useful during prototype testing to tell when batteries are low.)
  • Clean up existing code… Remove dead code, number sections consistently.
  • Document the present proto board design…  Draw a reference schematic… Also for the little LED/button board.
  • Maybe go ahead and get an Arduino Mega 2560 so I can continue programming without the annoying code-size restrictions…
  • Maybe build a new hand-wired perfboard prototype with the following new features, to make a cleaner prototype:
    • Big capacitor(s) for supply-voltage level smoothing.
    • Battery-reversal protection circuit(s) on the polarized capacitor(s).
    • Switching voltage regulator, to run down all 3 of the +9V batteries more evenly without wasting their energy, and to enable them to be run down farther before system stops working.
    • Voltage divider for battery-voltage level-monitoring system.
    • Pin reassignments to allow PWM output on the LED-driving pins.
    • Orient so there is room to install the Arduino Mega 2560 in place of the Uno.
    • New connectors to go to LED/button board (6-pin ribbon), and to the LCD panel (16-pin ribbon).  And to the batteries.
    • Get a clip that holds three 9V batteries, make one connection from it to the board.
  • Maybe go ahead and source a new battery solution.

On this day (Fri., 8/11) I also brought my labelmaker home from the lab, and put new, cleaner labels on the prototype:

New labels on prototype

New labels on prototype

Friday, Aug. 10th

Some more little things I could do to wrap up the prototype (tweaks, etc.).  Most of these are optional.

  • [/] Set up battery-level indicator to blink when battery level is low (in bottom 25% of range).
  • Wire up battery-level indicator to main 9V battery with voltage divider; calibrate readout to give a useful reading of its voltage level.
  • [/] Squeeze the time-zone name display back in.
  • Find & install an alternate bootloader that allows the code size to be larger.  (And/or get a direct-burn programmer.)

Working on squeezing the time-zone name display back in, because I really liked that feature.  (Because, who really wants to read “GMT-04” or “GMT-05” and think about which one is Eastern time depending on what time of year it is?)

Current (v0.7) code size:  28,696 bytes.  It seemed to fit at first, but then I got an error.

Now 25,658 bytes.  Fitting again.  Oops, forgot to clear the time-zone name when not a standard one.

Now 28,678 bytes.  No fit!  It is very strange, I can make a very small change to the code that ends up affecting the code size quite a lot.

Now 28,634 bytes.  Barely fits!  This suggests other stuff (just the bootloader?) is taking up about 3.5 KB.  Strange since I thought the bootloader was only 2K.

I looked a little into skipping the bootloader, but that requires buying additional hardware – the programmer.  So let’s descope that for now and continue working with what we have.

One thing we could do is rip unused code out of the Time.cc library.  We only use setTime(hr,min,…), adjustTime(), and the functions now() and year(),month(),day(),hourFormat12(),minute(),second(),hour() with a time-struct argument.

That got us down to 28,480 bytes.  Let’s make sure it still works…  Yep, seems to.  Maybe now we have room for battery-blinking code?

Added blink code.  Now at 28,608 bytes.  Fits.  OK, battery level indicator now blinks whenever it is low.  (Still not wired up to the real battery though.)

Thursday, August 9th

Trying out the sample sketch that reads lines from the GPS and logs them to the SD card.  Couldn’t tell from its serial output if it was working in my office, so putting it outside for a bit to make sure it has a chance to receive some real GPS data.  (It may have been working anyway, and just not displaying any diagnostic text; we’ll find out.)

OK, there was no data in any of the “GPSLOGxx.TXT” files produced – just empty files.  So I still can’t tell if any GPS data was received.  Let’s look back at the script.  It looks OK.

Ugh.  Now looking at the Eagle schematic for the GPS/datalogger shield.  It looks like pins 10-13 (not just pin 10) are reserved for use by the SD card interface.  So, we couldn’t use pin 11 as the on/off signal after all.  We’ll have to go back to pin 0 or 1 (although they didn’t work before) or else use one of the analog pins in digital mode.  Where is my chart of the analog pin assignments?  Ah, back in the blog on 7/27.  Damn, all the analog pins are in use.  Guess we’ll have to try digital pins D0 & D1 again…

Great… That didn’t work, and, looking at the Arduino schematic, it seems that those same two pins (D0 & D1) are used for the main serial I/O… Which explains why they didn’t work before.

So basically, there are not enough pins on the Arduino to simultaneously use the LCD, GPS and SD card unless we completely turn off the diagnostic serial interface.  That will make things pretty difficult to debug…

I suppose we could just wire the GPS power pin constantly to ground, that way it will be on all the time…  Yeah, that’s the ticket.  With that done, now initializing the SD card no longer messes up the GPS output.  Whew.

Commented in the code to create the file.  Great, now the upload is failing.  Could be a file-size issue; we’re over 30K.  I could try a different bootloader, but first let me see if shrinking the image fixes the problem.

Took out Turf-Tec name/address from file header.  Size:  30,328.  Still having problem.

Took out custom glyph stuff.  Size:  30,068.  Still no work.

Took out some other stuff.  Now 29,972.  Still no luck.

Let’s retry uploading version v0.5.  That worked.  It is 23,332 bytes.

Took create-file back out, now we’re at 24,948 in v0.6.  That uploads, but a bunch of stuff is missing.

Added custom glyphs back in.  Now at 25,236 bytes.

Added empty create_file() function.  Still at 25,236.

Added a println() in.   Now at 25,286.

OK, #if’d out the serial diagnostic code.  Now at 24,066.

OK, added create_file() code back in (except for serial stuff) – now 29,056.  No fit!

#if’d out serial initialization.  Code size now at 28,766.  Still no!  (At this point, we are no longer using serial I/O at all, so we could go back to using pin 0 or 1 to turn on GPS instead.  But, no matter…)

Took out meat of checksum-verification.  Now 26,824.

OK, it loads and says the file was created.  Let’s check the SD card to make sure.

Yep, it worked; created TURF-T00.CSV with a file header.

Commented out some more stuff.  Now 28,256.  Still fitting.

OK, added all the SD code in.  Now 29,108 bytes.  Probably not going to fit now.

Removed some more stuff.  Fitting now.  Doing an outdoor test.

Great… After fixing a couple of minor output formatting issues, all is good now.

I changed the Discard pushbutton to say “CLEAR” on the screen (instead of “DISC”) and to always reset the last measured Gmax value to 0.

Here is an example output file produced:

DAY,TIME, GMAX VALUE ,LONGITUDE,LATITUDE
8/9/2012,10:16:47 PM,22,30.5961818695,-84.5869598388,
8/9/2012,10:17:3 PM,30,30.5961799621,-84.5869598388,
8/9/2012,10:17:18 PM,18,30.5961570739,-84.5870285034,

Ah, there’s an extra comma at the end of each data line – fixed that.

Note the latitude and longitude are now decimal degrees only (no minutes or seconds), which allows the coordinates to be directly copy-and-pasted from Excel (or notepad) into Google Maps or Google Earth to verify the location.

Last thing I did before bed:  Made a video of a demo run.

Wednesday, Aug. 8th

Fixed a minor bug with the battery-life display.  There are really only 8 custom characters (#1-8).  We are using 4 for special symbols (satellite, degrees, minutes, seconds), so that leaves 4 for the battery-level.  (I had been trying to use 7.)

LCD is working OK at the moment (except for partially faded area), but it frequently still has problems…  I think it is an issue with the cable/connector between the board and the LCD, since fiddling with the cable frequently seems to cause/fix the problem.  We need a permanent solution anyway for the LCD/board interconnection.  I tried to find some suitable pre-manufactured cables online, but no luck yet…

Probably we will end up having to make our own cable assemblies.  Here for example are (I think) suitable connectors:

And here is ribbon cable that (I think) should fit it:

And, here’s another connector that might work better with that cable:

Also asked Molex for a quote on complete ribbon cable assemblies:

Now working on the SD card code…  Initializing the SD seems to be freezing the GPS output for some unknown reason… Ugh.  Should probably try the sample sketch…

 

Back from Vacation

Returned from vacation yesterday.  Planning to spend a little time today testing the code changes I made while on vacation (to implement the set-timezone feature).

First, re-testing the existing firmware.  The unit seems to be failing to acquire satellites while indoors…  Probably its ephemeris data expired while I was away.  I am going to take it outside and try again.

Or, maybe it is a battery voltage problem, or something else?  Need to diagnose…

OK, apparently the problem was that the GPS module forgot its settings while I was away, and it was trying to communicate at the original baud rate (4,800).  (I need to write some code that automatically tries a couple of different baud rates to handle this properly in case it happens again…)

The new LCD panel arrived but it is missing the SIP header.  Have to go pick one up from Fouraker tomorrow…

OK, now trying new code… (version 05 of the firmware)

Debugging time-zone setting mode…  Basically working… Fixing a few minor bugs.

Timezone-setting mode

Timezone-setting mode

It is working fine now.

I think I can program it to automatically figure out if we’re in daylight savings time or not…

OK, now in timezone-setting mode it displays labels EDT, CDT, MDT, and PDT for time zones -4 through -7 during the US daylight savings time part of the year (Mar.-Nov.), and EST, CST, MST, PST for time zones -5 through -8 during the US standard time part of the year (Nov.-Mar.).  It switches on the 2nd Sunday of March and the 1st Sunday of November as per current US law.  Note: When the switchover occurs, the unit will not automatically change time zones (it isn’t saved yet anyway).  All that happens is that the label that appears in the timezone-setting mode will change on the next button push after the switchover occurs.

Also:  times between 1-2 am on the day of the switchover are treated as if they are in DST (regardless of whether they really are or not).  So for example, 1:30 am in GMT-4 is displayed as “EDT” on the March switchover date, even though GMT-5 is 12:30 am EST at that time and technically no one is supposed to be using Daylight Savings Time yet.  And in November, 1:30 am in GMT-4 is correctly displayed as “EDT,” but then an hour later, when it is 1:30 am in GMT-5 (EST), that will be displayed as “CDT” instead when we are in the GMT-5 time zone.  However, these glitches only occur for an hour in the middle of the night twice a year when the user happens to be trying to set the time zone, so they are not a big problem from a usability perspective.  Also, the user can always ignore the labels and just pay attention to the GMT+/-nn  time zone designation instead, if they know what they’re doing…  Or just compare the time shown to a reference clock.

NOTE:  In theory, the GPS coordinates could be used to look up the geographic locale and infer the correct time zone / daylight savings setting directly from that, but this would require a very extensive database and is way out of scope for a product of this level of complexity.  Also, some users may wish to save data using a different time zone than the one that is in effect where they are physically located.

Noticed the EEPROM library which looks like I could use it to remember the user’s time-zone setting.  OK, did that – that works now.  This raises the possibility of also saving other preferences.  Not sure what yet…

I could add a feature to automatically switch back and forth between standard time and (US) daylight savings time (by remembering which one the unit was last in), but then I would need another function to switch this feature off and on, since some users (e.g. ones outside the US) may not want it…

Time Zoning

Spending a little time during vacation working on code to enable setting time zone.

I’m wondering if I should use the TimeAlarms library to setup various delays…  However, looking through the library code, I’m not understanding exactly how it’s working…  It doesn’t use interrupts, so how does the alarm get invoked?  It looks like I have to explicitly call Alarm.delay() or something in order for it to get a chance to go off.

Things I could use maybe alarms for:

  • Leaving refractory mode a couple of seconds after impact.
  • Leaving time-zone mode 5 seconds after the last button press.
  • Updating time display every second even if GPS is not responding?

Still not sure I want to do this though.  The alarms may not be flexible enough…  I think I’ll continue to just handle my timing functions manually for now…

I think I finished the code changes to implement the time-zone setting mode.  However, of course it still needs to be tested.  That will have to wait until I get back home…

Also making minor code changes to minimize the number of global variables.