Thanks for doing that, Liam. Looks brilliant. There are some clumsy pieces of coding in there. I think I’ll leave them and users might exercise their coding skills and refine what I’ve done.
Hi Alan. I’d never be able to learn assembly to tackle this. Why do you only work in assembly? Do you design embedded devices? There’s a notion around that the Arduino processor runs much faster than the serial port so there should be no problem doing tasks between reading the serial buffer. I’m finding I can’t trust that notion. i think I need to grab and store all NMEA in a cycle while doing an absolute minimum of tasks, and when I have them all use the rest of the cycle to run the “mainline” work. The serial buffer is 64 bytes; the sentences transmission takes about 0.4 sec leaving 0.6 sec for the mainline work.
Good question! Part of it is frustration with microprocessor C, one is not sure what goes on in the background. Part of it is the desire to wring the last ounce of performance from an 8 bit processor rather than cave in to ‘get a bigger hammer’ syndrome. And I like the puzzle aspect - how can this be done?
It is possible to combine assembler and C, I did this for an ATmega328/P a few years back. From memory the C compiler allowed in line Assembler, and ISR (Interrupt Service Routines) to be declared ‘naked’ which means C doesn’t put a wrapper around the interrupt and the assembler handles it all.
Back to your problem. You seem comfortable with the idea of waiting until all NMEA messages arrive before going off to process the data. I don’t know how much memory you have available, but a possible way out is to handle the serial input in an ISR written in C. All the ISR need do is write incoming characters to a circular buffer say 32 bytes. When the 32nd byte is written, start again with the first byte. Excuse my code, it is pseudo C
#include <avr/interrupt.h>
ISR(ADC_vect) //vector names provided by compiler
{
buffer[inpointer++]=RxChar; // move character from UART to memory, increment pointer
if (inpointer>31)inpointer=0;
}
The mainline has a pointer also that tracks inpointer. While mainpointer=inpointer there is nothing to do.
If mainpointer<>inpointer // lots to do
{
If readingflag=yes then
{ If buffer[mainpointer]=* then {readingflag=no; call a function to analyse the message[]
else message[x++]=buffer[mainpointer];
}
else If buffer[mainpointer]=$ then {x=0; readingflag=yes}
}
if (++mainpointer)>31 then mainpointer=0
}
The reason for this somewhat roundabout method is you can read 32 characters from the UART while processing the previous message. That should be plenty of time to extract what you want from the message.
Once you have all the data you want from the messages then do other processing, come back to the
If mainpointer<>inpointer
section. It doesn’t really matter if the pointers don’t match, readingflag is no until a $ is read.
Thanks. I made the effort to create accurately dimensioned models of all the boards and components. I then used those models to create the spaces to receive the actual components. I turned the Nano model into a hole and lowered into the box shape. It leaves indentations exactly where the pin-holes of the real Nano will lie.
So the Tinkercad drawings are not just a realistic representation of the finished assembly but are key to the design process.
With the current design it is difficult to install the wiring between the components. The housing is a hollow box. There are apertures for each board and the other components. The interconnections are made by placing short lengths of wire inside the box and soldering the ends to thru holes on the boards and the pins of the buzzer and dip switch. This is awkward and time consuming – there is not much space; wires need to be long enuf to be manipulated but if too long they push back like springs when the boards are put into their resting place.
Here, the housing is a solid block, not an open box. The inside of the block is hidden and inaccessible. Small ducts are designed into the monobloc to provide conduits for wires to connect thru hole to thru hole. The idea is a wire is pushed into the opening at one end of a duct until it emerges at the opening at the other end. So the wires will be precisely where they are needed and don’t have to be manipulated. Looks promising. Have to suck it and see.
Very interesting problem! I’d also take a look at this forum topic for some ideas Given you are working from all sides rather than one there’s a chance it would be harder but worth a look into!
These are jumper wires. They fit snugly into the ducts which are 2.0 mm diameter. So i was able to get these thru each duct but I think it will be too tricky to solder to the boards. The insulation wud have to be stripped back to the housing surface. They are multi core which makes them nicely flexible but the fine wires are tricky to get into a thru hole for soldering. I found, when soldered, they can break easily if manipulated too much.
Here I’ve used single copper core hookup wire. Have inserted all wires. I can strip off as much or as little insulation as I need to. Once the wires are soldered to the boards and the boards flush against the housing I’ll trim off the excess copper wire. This is turning out to be a good technique.
Be very careful with this. When stripping do not touch or nick the copper. If you do it stands a very good chance of breaking when you push a unit back into position.
I am surprised you found stranded wire breaking. In my experience stranded wire withstands flexing much more readily than solid. The exception here is if too much solder “wicks” down the wire, then it is likely to break where the solder wicking finishes.
Cheers Bob
Hi Bob. Thanks, I’ll try to avoid nicking the wires, which I often do.
I put the breaking down to too much manipulating of the boards and hence the soldered connections and the fine wires themselves. Also, I can’t be sure I’ve soldered all the individual wires into the thru holes. The real problem is the cramped working space because the boards have to be close to the housing while I solder the connections – if the wires are long they can’t be pushed back into the housing. I’m hoping that with this new method I’ll be rid of this problem. We’ll see.
Sounds like your soldering skills could do with a brush up.
Cheers Bob
PS. Otherwise you have done an excellent job here with this project. Congratulations.
Here’s a view of the ducts that might be easier to comprehend. Each has to be the right length, height and at the right angle. And they musn’t foul each other. A good puzzle.
Hi John
I am not trying to be too critical here. You have gone to an immense amount of trouble to get an extremely good project up and running and congratulations are well in order.
BUT. At the end of the day you seem to have used bare, untinned copper wire. I don’t quite understand.
Cheers Bob