anchor chain counter to NMEA0183 Garmin proprietary sentences via arduino?

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
6months on and I'm happy to report that today I finished off (er, almost...) the installation and everything is now on board connected and working.

Fitting the bleeding magnet and sensor on a Lofrans Tigress windlass is a PITA and as fitted now picks some of the turns of the windlass and misses a few. So got to bring the sensor closer to the magnet on the windlass. I'll also try reducing the delay of the main loop checking for closed circuit on the sensor as I feel the 50ms was fine for tests at home passing the magnet leisurely over the sensor, but the gypsy turns v.fast and seems that the close circuit delta is way too small to be picked. Will hopefully sort it tomorrow as I'm about to leave for week or so with the boat.

Having programmed the MEGA (burnt the Due on testing...) I've now setup all sorts of other things on the same code but not installed the sensors on board as yet. Have tried them at home though and all seems to work:

  • NASA NMEA0183 windsensor to N2K (way cheaper than getting a proper N2K windsensor)
  • pressure based tank level to N2K (for diesel and/or water tanks) Handy if you cannot drill a hole to fit a proper sensor from the top of the tank
  • temp for exhaust flex hose as well as seawater temp at the elbow just before mixing with exhaust gasses, again to N2K
  • old analogue CETREK rudder sensor to N2K


have a few more I'm considering but that will be next winter projects...
All is based on the generous help received in here and the great project by Timo a Fin guy on github (https://github.com/ttlappalainen/NMEA2000)
Needless to say, if anyone needs code/ideas/help/bits I've used on all that, just shout!

I'll report in detail on the main rebuilt thread of MiToS in the mobo section of the forum

cheers

V.
 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,517
Location
Hopefully somewhere warm
Visit site
Well done! :cool:

Tried an esp8266 yet? More fun waiting. Like an arduino with built in wifi so you can send data as udp or even host a website with one. Cheap as chips as well.

Is your code online anywhere? Always things to learn/steal from other code :)
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
Well done! :cool:

Tried an esp8266 yet? More fun waiting. Like an arduino with built in wifi so you can send data as udp or even host a website with one. Cheap as chips as well.

Is your code online anywhere? Always things to learn/steal from other code :)

:D
got wifi from the one plotter replicating the screen to any tablet/mobile phone.
Got wifi from the SJCAM4000 showing what the kids shoot underwater in the tablet/phone
having yet another wifi is probably a bit too much tbh :p
Having two plotters one on each helm and not having a 80ft boat means I can live with all the info I get from them

I'm off for a week, I'll sort out the comments a bit and zip it up and post it on my webserver where all the rebuilt pics are.
If I've not done it by the beginning of Sept, drop me a note

When I was working on my own design I used a reflective sensor that registered the hole in the drum.
Nigel,
although I'm pretty sure I'll sort out the magnet one today, would you care to elaborate your design? There's no hole in the drum I can think of.
I'll post a thread on the topic on the mobo forum when I get some time

cheers

V.
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
typical!

got the magnet and sensor distances right, but system updates are unfortunately 1 in 3 or 4 or 5 gypsy rotations depends... Practically making the whole system useless!

Gypsy rotates rather quickly and definitely much quicker that me testing the sensor and magnet on my desk...
I feel that with my coding there's not enough time to pick the event of the bleeding pin HIGH ...
Am I correct in saying that there's no (easy) way of prioritizing a process in arduino?

I mean I want to have a tight loop checking the pin state for D45 and a counter on it not missing a beat.

Then I want to query this counter and every sec or so construct a NMEA0183 message and send it down to the GMI10 for the display. Don't mind if the updates are on exceptionally quick intervals, I just want the right distance to display at the end of the day!

Is something like that doable? I'll clear up my code and post it here for any comments

cheers

V.
 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,517
Location
Hopefully somewhere warm
Visit site
typical!

got the magnet and sensor distances right, but system updates are unfortunately 1 in 3 or 4 or 5 gypsy rotations depends... Practically making the whole system useless!

Gypsy rotates rather quickly and definitely much quicker that me testing the sensor and magnet on my desk...
I feel that with my coding there's not enough time to pick the event of the bleeding pin HIGH ...
Am I correct in saying that there's no (easy) way of prioritizing a process in arduino?

I mean I want to have a tight loop checking the pin state for D45 and a counter on it not missing a beat.

Then I want to query this counter and every sec or so construct a NMEA0183 message and send it down to the GMI10 for the display. Don't mind if the updates are on exceptionally quick intervals, I just want the right distance to display at the end of the day!

Is something like that doable? I'll clear up my code and post it here for any comments

cheers

V.
Are you using an interrupt to read the pin?

Have a look here...

http://playground.arduino.cc/Main/ReadingRPM
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
Are you using an interrupt to read the pin?

Have a look here...

http://playground.arduino.cc/Main/ReadingRPM

yeah right, haven't got even time to check what I'm using as I'm leaving for 10days tomorrow morning, a scrote stole one of the oars from the rib (the bad things related to Med stern to mooring on a public marina...) and I've got to source a pair or oars for the morning,.. To make matters worse, tomorrow is the greatest summer holiday down here and everything is closed!

just cleared, zipped and I'm linking to the code. That's just the autoanchor routine I want running now. I'll post the rest with decent commenting sometime next week

If you think there's something I can do to improve that, fee free to post!
I may have some time late at night to try and figure out what the code you posted does, else I'll try and get a morning up before all the others and have a go on the laptop on board :D

cheers

V.

CODE http://fos.prd.uth.gr/vas/crafts/mitos/var/Autoanchor_MEGA_MCP.zip
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
must have spent at least 5h to sort this mess out.
Got the interrupts and how they work and programmed them in fine, thanks GHA!

Now however, since I'm using a reed switch I have to bleeding debounce the signal.
Trying different settings on my loop for a s/w debounce, and it seems to work okayish
However on slowish passes of the magnet I may get two triggers, which is not nice.
I also occasionally get something like 20-25 triggers so seems like 7-8m of chain just dropped in a split second, that's plain silly.

Working at home with the reed switch installed on the windlass is not v. helpful, will try it on site tonight.
Seems like I'll have to get a decent h/w debounce circuit and tune it properly (all that without any oscilloscopes or similar monitoring h/w around) in order to get reliable values out of all that.

Amazed at how small details can ruin weeks of effort till they are properly fixed...

cheers

V.
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
On the first trigger, disable the interrupt and delay for a while, make sure interrupt latch is clear before returning.

Nigel,

I'm not a programmer and I have to confess that your suggestion (which is absolutely reasonable, logical and clearly understandable) is easier said than done!
I cannot use millis() to count time and do some checks within the ISR, so it seems that the only way forward is to set flags each time ISR is activated due to pin going HIGH or LOW, do some comparisons and delay checks outside the ISR and THEN come back to the ISR test a combo of flags (say the one for LOW + the time delay test flag) and only then update the counter...

I can easily do that lot WITHOUT the Interrupts but I guess it's not a clever idea.
A rather convoluted code is ready for testing tomorrow morning, fingers crossed it will work!

Pity I cannot get hold of a Hall sensor or optothing for my gypsy and good thing that Olympics are over so there's nothing to watch on the TV for another 4yrs and I can get some work done :D

cheers

V.
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
On the first trigger, disable the interupt and delay for a while, make sure interupt latch is clear before returning.

success!

Nigel, 8ms interrupt delay was enough, now dropping the anchor is spot on (I may "loose" 1 gypsy turn on 60, effectively .3m on 20m which is nothing...)
I'm now trying to sort out the retrieval where on 20m I'm off by 3 or 4 gypsy turns (1-1.5m) not much but annoying.
Seems that I have to stabilise the current coming to the analogue input pin (through a current divider) which is the trigger for my code to start cnt-- instead of cnt++
Looks like on starting to retrieve sometimes the first gypsy turn goes + instead of -. If I stop and start the retrieval a few times the error increases.
Further once I release the up toggle on the windlass, the following UP turn of the windlass registers as DOWN as the trigger current is not there (obviously) so a 2-3sec delay is also needed there.
300lines of (commented) code is a lot for a simple process like that, but if it works I'm fine and I'm not even mentioning the 100s of hours of learning, programming, searching and soldering in order to accomplish that.

Fine tuning and testing on the w/e in real conditions...

cheers

V.
 
Joined
20 Jun 2007
Messages
16,234
Location
Live in Kent, boat in Canary Islands
www.bavariayacht.info
... it seems that the only way forward is to set flags each time ISR is activated due to pin going HIGH or LOW, do some comparisons and delay checks outside the ISR and THEN come back to the ISR test a combo of flags (say the one for LOW + the time delay test flag) and only then update the counter...

No need to come back to ISR. Here is some of my code, hopefully you can follow it.

Interrupt function
Code:
// Interrupt function for Chain Counter

#include "defs.h"

void interrupt() {
     unsigned short snapshotB ;
     if (INTCON.RBIF && INTCON.RBIE)
     {  // RBIF set by change on PORTB b4-b7 (see Data Sheet P101)
        snapshotB = PORTB ;      // end any mismatch before clear, take snapshot
        INTCON.RBIF = 0 ;        // clear interrupt flag, signals to main()
        INTCON.TMR0IE = 1 ;      // enable TMR0 display (in case wake from sleep)
        mode = 0 ;               // zero up/down marker
        
        if ((snapshotB.up) || (snapshotB.down))
        {
          sleepTimer = 0 ;         // reset sleep timer on any button
        }

        if (snapshotB.sensor == sensorActive)
        { // sensor switch fired
          INTCON.RBIE = 0 ;    // disable PORTB interrupts, turn on in main()

          if ((snapshotB.up) && (snapshotB.down))
          { // up and down buttons both pressed so reset counter, mode is 0
            count = 0 ;              // reset counter
            ledUP = 1 ;              // turn UP LED on
            ledDN = 1 ;              // turn DOWN LED on
          }
          else if (snapshotB.up)
          { // up button pressed
            mode = -1 ;              // decrement count on next update
          }
          else if (snapshotB.down)
          { // down button pressed
            mode =  1 ;              // increment count on next update
          }
        }
      }
      if (INTCON.TMR0IF)
      { // timer0 interrupt
        INTCON.TMR0IF = 0; // Clear interrupt flag bit
        display() ;        // update 7-segment LED display
      }
}

Main loop
Code:
/*
Project name:  Chain Counter MK2
Copyright:     (c) Nigel Mercier 2012
Description:   Counts pulses on chain gypsy and displays length of chain

  O/P: 7-Segment Displays RC0 to RC6 (RCz7=DP)
  
  I/P: PORTB b4 magnetic sensor on drum, b0 & b1 direction buttons
  Segment: A=RC7 B=RC6 C=RC2 D=RC1 E=RC0 F=RB1 G=RB0 DP= in parallel RA1 (D2)
  Common Cathode: H D1=RA0 T D2=RA1 U D3=RA2
  LEDs: LED1=RA5 LED2=RA4 LED3=RA3
  
* Test configuration:
     MCU:             18F2550
     Dev.Board:       Custom
     Oscillator:      INT, 08.0000 MHz
     Ext. Modules:    -
     SW:              mikroC v5.3
*/

#include "defs.h"

unsigned short dummy ;
unsigned int pulseTimer ;
unsigned long int sleepTimer = 0 ;
signed int count = 0, test = 0 ;
signed short mode = 0 ;       // counter mode: down is +1, up is -1
const float ratio = 0.345 ; // multiply ratio by count to get metres


void main()
{
  init() ; // initialise variables, registers and ports
  do
  { 
         if (INTCON.RBIE == 0)
         { // signals that a PORTB interrupt has occoured
          pulseTimer = 0 ;          // prepare to time sensor pulse

          while ((PORTB.sensor == sensorActive) && (pulseTimer++ < 1000))
          { // wait for sensor pulse to finish, or timeout after 1 second
            Delay_ms(1) ;           // time sensor pulse for valid duration
            pulseTimer++ ;
          }
          if (pulseTimer > 20)      // 1 rev = 500mS (2RPM) M:S optical is 1:20
          { // come here if valid pulse time ~ 500/20 = 25mS
           count = count + mode ;   // update count of revolutions by +/- 1
           if (mode == -1 )         // was UP button pressed
            ledUP = 1 ;             // turn UP LED on
           else if (mode ==  1)     // was DOWN button pressed
            ledDN = 1 ;             // turn DOWN LED on
           Delay_ms(50) ;           // debounce delay
          }
          dummy = PORTB ;           // end any mismatch prior to flag clear
          INTCON.RBIF = 0 ;         // clear interrupt flag
          INTCON.RBIE = 1 ;         // enable PORTB interrupts, ready for next
         }
  
         if (sleepTimer >= 4096 * 37.5)
         { // 4096 is 16 seconds, 37.5 multiplier gives 10 min (600s)
           ledT = 0 ;                  // turn off all segments via commons
           ledU = 0 ;
           ledUP = 0 ;                 // turn off up & down LEDs
           ledDN = 0 ;
           ledRD = 1 ;                 // red LED & no display indicates sleep
           
           INTCON      = 0b10001000 ;  // GIE=1, TMR0IE=0, RBIE=1, clear flags
           ledIR = 0 ;                 // turn off IR source
           asm sleep ; // wake on B interrupt, sleepTimer reset in ISR by button
           ledIR = 1 ;                 // turn on IR source
           INTCON      = 0b10101000 ;  // GIE=1, TMR0IE=1, RBIE=1, clear flags
         }
    }
  while (1) ;                        // endless loop
}

I suggest you change the up/down inputs to digital, the circuit diagram for my main board is here
 
Last edited:

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
hello,
unfortunately I cannot ask or thank Nigel :(

so, a year later, back to report on this project.

Last summer I did indeed fit the whole system onboard, wired everything up, but it never worked OK, dropping chain would be okayish, up would be all over the place, so gave up.
further on the season, the reed got a few good smacks from the chain jamming, so it was completely knackered.
Anyway, since I have some time this month, went through the lot, sorted out the code for my NMEA0183 windthing -> N2K as well as my old analogue CETREK rudder sensor again to N2K and a couple of talk level sensors (again not N2K) so have everything work (er, almost!)

So back on board, spent at least a dozen hours debugging the code as behaviour was "strange". Using a new reed well protected from chain mishaps with a thick alloy shield, so signals definitely coming to the box but slightly off on dropping chain, and WAY off on retrieving (like 4X the counts...). Typically every DOWN press and release will register 3-4(mostly) extra turns and that's generally independent of duration of drop. So if I drop 3 turns it registers 7 and if I drop 20 I'll get 22-23 (slightly less the longer)
To make life easier, I have removed the chain from the gypsy and have added a flag so that I can see/count gypsy rotations and compare to code output.

After a lot of headscratching, today got the box back home and wired it up with another identical reed thing and using a stabilised 12V supply to feed the voltage divider I employ in reading the UP button signal in order to count down gypsy turns and get values right.
Amazingly it all worked perfectly at home not missing a single gypsy turn!

Then I started thinking of noise from the 1800W Lofrans 24V motor, the Quick relay, cabling and all that jazz.
So coming to the conclusion that electromagnetic noise must be dealt with.
Now being a cheapskate, I used a left over bowthruster signal cable to bring to the lower helm the signal from the reed switch and the 24V signal from the UP of the Quick relay. My guess is that's a signal party going on there in the 6-7m of travel.
To make things worse, I really DONT want to rip bow and side cabin upholstery yet again and route a decent shielded cable through, so looking for solutions.

I'm going to first of all use a completely different cable through the door to the bow cabin to get the 24V signal to the arduino and see if that fixes it, if the answer is yes, I'll have to either get the signal from the windlass switch on the lower helm or think of something else.
I'm wondering if optoisolation (which was discussed in a slightly different context a year and a half ago) would help. Current counting to the trigger wire going to the relay box is not going to cut it (I recon)
I'm off to the boat to test ext wiring and will report back!

cheers

V.

PS. I'll probably start another thread explaining the routines I've written and what they do, what h/w is needed etc. Wasn't a overly complicated system for a beginner like me and imho well worth it compared to having to remember to count secs everytime I dropped the chain (haven't got markers on my chain...)
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
Why not just put markers on your chain, like everyone else?

few reasons...

  • usually helming from the f/b, and typically bow cabin hatch is open to let the wind in and keep cabins cool. So I cannot see windlass and chain, bar the last bit over the bow roller. Would easily miss a marker.
  • I've got two Garmin GMI10s one on each helm station and it does support the AutoAnchor routines, so it can show depth, wind, rode etc in one screen which is handy on unknown anchorages.
  • I wanted to use the arduinos and do a series of other conversions of analogue date to NMEA2000 so that's part of the whole project.
  • winter nights even in Greece can be dark, cold and boring, this sorts it :)

Please keep us posted :encouragement:

did some tests last evening but didn't have enough time to draw definite conclusions, so just some observations:

routed a new cable from the reed to the helm, worked better wasn't counting the extra rotations on down.
as long as up signal is wired to the quick relay box, up rotations are all over the place, so first need to address that. I'll try both an optoisolator and before that a current sensor just in case it actually works (doubt it)
reed cable goes AROUND the motor and down with the thick power cables to the anchor locker. I feel that's part of the problem. A bitch of a job trying to shield this thin cable...
I've used a proper shielded bus cable (the green 4 core one) to get the signal from the anchor locker to the helm (so not much of a cheapskate...). I've used the green and blue (or whatever) for the reed signal and the red for the 24V UP signal. Black is unused and shield is free. Got to use both of them and ground them, see if that helps.

If it turns out that reed cables pick up noise from the actual motor as they are routed down the locker, I'll just drill a small hole and get the signal down a completely different route, but I'd rather avoid that tbh.

If I could get hold of an oscilloscope (and someone to tune and use it :D ) I would decide straight away what's wrong... Can I turn my notebook into a oscilloscope with the help of an arduino by any chance?

cheers

V.
 

GHA

Well-known member
Joined
26 Jun 2013
Messages
12,517
Location
Hopefully somewhere warm
Visit site

prv

Well-known member
Joined
29 Nov 2009
Messages
37,361
Location
Southampton
Visit site
Can I turn my notebook into a oscilloscope with the help of an arduino by any chance?

Probably, but then you'll get sidetracked into a whole different project :)

You can buy USB adapters which use software on the computer instead of a physical display, making them pretty cheap. I have one of these which costs $20 and works pretty well on my Mac and a Windows laptop.

Pete
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
Probably, but then you'll get sidetracked into a whole different project :)

You can buy USB adapters which use software on the computer instead of a physical display, making them pretty cheap. I have one of these which costs $20 and works pretty well on my Mac and a Windows laptop.

Pete

thank you very much for helping me burn some more euros... Placed an order on the German site as the UK one didn't stock it and not keen on getting it from over the pond.
[I'll probably have sort it by the time it arrives, but I have other things in mind that a signal generator and monitoring is needed]

cheers

V.
 

vas

Well-known member
Joined
21 Jun 2011
Messages
8,084
Location
Volos-Athens
Visit site
closing the thread!

so, turns out that my programming was fine, it was the routing of cables to blame...

NEVER pick the windlass up signal from the relay box, too noisy environment there, go to the nearest helm toggle and pick it from there (much shorter distance after all)
USE SHIELDED cable on the reed sensor route from the windlass up to a safe/not noisy environment and ground the shield!
In the Lofrans Tigress I had my tiny unshielded sensor cable run for about half a metre either by the thick cables running the winch, or almost touching the winch motor. Not clever...
Best test is to route the cable to the sensor, remove the magnet or the gypsy and try the winch, if the system counts turns, that's all EMI, do a better routing.

Summing up I used:

  • 1 Arduino Due - could be Mega (slower), or teensy (smaller but fast)
  • a MCP2562 dip chip
  • a resistor to make a dodgy mod to the older Due I had, so better ask before you buy!
  • a 100nF capacitor
  • a stabilised powersupply would be nice as NMEA2000 supply is 12-13.5V and the chips prefer something smaller...
  • serial->TTL chips
  • originally a v.expensive marine sensor on a nice flimsy plastic mount, broke it, and used an oldfashion door alarm sensor (1euro...) on a custom robust mount.
  • box, breadboard, screws, plugs, NMEA2K sockets
  • a soldering gun and some patience.


Cost for the lot above in h/w was probably less than 50euro (depends on which arduino board you choose and if you want a proper NMEA2000 socket to plug your proper cable onto, or are happy to cut a cable and use chock blocks)
Of course this lot wouldn't be possible without the work of Timo Lappalainen and his excellent code on github which you'll need to download and the help from half a dozen ppl in here, thanks!

What I've done is simply wire various analogue or NMEA0183 devices up and convert signals to NMEA2K and feed them to my network so that data is replicated all overboard on GMI10s (20s if you have) and GPSMAP chartplotters.

Data working are:

  • anchor chain counter - NMEA0183 proprietary protocol by Garmin to support AutoAnchor black box. 2way communication with the GMI10 means I can set parameters, reset rode, and alter gypsy circumference as well as sent rode and gypsy speed info to the GMI
  • NMEA0183 NASA wind -> N2K (180euro iirc, much cheaper than proper N2K windsensors)
  • analog rudder sensor (CETREK) -> N2K
  • Phillipi analogue Ultrasound black water tank sensor ->N2K (cheapest I found at approx 100euro)
  • FYES pressure sensor (water-fuel) ->N2K (excellent solution if you don't have a hole at the top of the tank to fit a proper sender, I think around 60euro)


For the winter, I'm planning on a second box in the e/r monitoring gearbox oil pressure (got the senders but not got real estate for the gauges, nor I want them tbh!), cooling water temp on the elbow, exhaust gas temps and a few more. I'll use a teensy as it's small enough and would make the box much smaller and easier to secure safely in the e/r.

I have a reasonably well documented code (he says...) and unless someone comes after 2 yrs asking how i did this or that, I should be able to help.

cheers

V.
 
Last edited:
Top