SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By dkulinski
#142341
Is there a fire selector switch built into the AEG? If so I bet there is an easy way to tie into the mechanics of that. It would feel more natural.

Dan
By StaticDet5
#142344
That's what I'm hoping for. For the "benchtop" testing, I'm just going to wire up a push-button.

Again, the problem with the AEG's is that each model is different. The P90, AR-series, etc, all have different mechanisms for selecting the fire mode. Also, this system potentially allows for more fire modes than the original model offers. Three round burst is very uncommon in AEG's, but is a feature that many folks want (safe, semi, 3RB, FA).

However, my main concern is to make the system. It's going to get taken far beyond that, once the "easy drop-in" part is accomplished.
By StaticDet5
#142375
In that vein, I'm updating the "To-Do" list, before I can think about making the PCB backpack:
1. Low Battery Cut-Out
2. Thermal Monitoring
3. Selector Switch (I have a cool part for this, but it's very limited)
4. Pin Breakout and Allocation (There are certain pins that are going to be common to every version of the board, others should be user available)

I'm really leaning towards NOT including the additional MOSFET cut-out. I'm reducing safety features, so it's a big leap for me to do. I don't think we're gaining anything by adding it, and it would increase complexity. It also seems to me that if that transistor fails, it could lock the MOSFET on. Right now, if the driving part fails, the whole system is going to be wonky (The MOSFET is driven by an analog pin on the Arduino).

I'm getting close to having to wire this thing up permanently (Dan, your wish is my command....)
I keep saying I'm going to get pics up of the pulse laser project. The board itself is a mess, and definitely a learning experience. I thought ahead and bought ten boards of the same size. I'm going to have to put in a parts order soon for headers, and I'm thinking about buying a 10' length of 10-conductor foil-shielded cable. It's slightly wider in diameter than the CAT-5 that I'm using now, but should offer even better performance. It will definitely give me better options for "stuff" at the end of the barrel.

Another big thank you to the folks on here. It's been a rough couple of months for me, and this project has really kept me going. It's incredibly motivating to have someone "stop by" and check your progress on something like this.
By dkulinski
#142377
It is quite exciting that you are moving past the proof on concept and onto a full blown prototype. Good luck with the work, I hope it all works out for you, I will be on vacation for a while and may not be able to participate much over the next week.

Dan
By StaticDet5
#142419
Have fun on vacation!

I'm playing with the display this week. I think I found what my problem was. It's going to be a bit of an uphill battle for me. The display uses a different language for programming. It's not rocket science, once I get beyond the serial commands. It would probably help if I had a better understanding of exactly how the serial data stream works in each system, but I'll learn through trial and error. At least I finally have the Arduino talking to the uOLED display.
By dkulinski
#142420
Having that screen will be great. I am sure you can pack a few indicators in that will help to know what state the AEG is in.

As for programming, does it retain programs across reboot? Can you write a program so simple serial commands update the display?

Dan
By StaticDet5
#142421
Yep. I can't rave about this screen enough (except for the learning curve, the price you pay for an insane number of options).

http://www.4dsystems.com.au/prod.php?id=85
OLED display
Able to be driven either through an onboard microprocessor (taking information from onboard I/O pins and serial) or directly through a serial port
160x128 resolution, 65K colors
Near 180 degree viewing angle
2x GPIO ports supporting an A/D converter, one wire joystick, sound generator and more
On-board uSD slot for storing.... STUFF!!!
5.5v tolerant
Ten pins total (I'm driving the display with three digital pins, GND, 5V. That's it)
All that for under $50

The fact that the display has its own microprocessor means I really don't have to worry about what the Arduino is doing, or processor load on the Arduino. The Arduino is just going to squirt information to the display, and the display is going to keep track of everything. I'm even going to use the display to log data when the system is matured. If I want detailed logs, I think I can just pop the uSD card out and read it direct.
By StaticDet5
#142444
Alright, I think we're at the next stage. I need to figure out the serial communication between the Arduino and the uOLED.

I'm not completely sure how serial communications work, so I'm going to talk out loud.
I think both systems are capable of communicating at 57600 (56K) baud. Baud refers to the speed at which the system can communicate bits (1's or 0's). We're going with the most common 8,N,1 protocol: 8 data bits, no parity, 1 stop bit.
If I understand correctly, 8 data bits (256 characters) can be encoded in each "data frame". The lack of a parity bit means no error correction in this protocol. If we use a parity bit, we could catch an uneven number of errors (1 corrupted bit being the most common number), but we'd miss even numbers of errors. The stop bit simply tells the system when it is done communicating a "data frame".
This means that at 56K, we have to divide by 8 (or 9?) to determine the number of characters we can send per second. We'll divide by 10, because that makes my head hurt less and gives us a bit of a buffer. That means we can send 5600 characters per second, right?
From the other direction, I think the max number of rounds per second is 30-40 (I haven't heard of a conventional AEG shooting faster than that). If we have 5600 characters to use, and we divide them equally among the 40 shots, that lets us send 140 characters per shot, or roughly one text message per shot. That's awesome.

I don't know if the serial link has any kind of error correction, checksum or anything. If it doesn't, I need to consider some sort of checksum at the end of the communication string, especially if I have this much communications room.

If that's the case, I think I'm going to use three part alphanumeric groups for serial communication. This will allow for an incredible number of different messages. Even if i cut the maximum message length by an order of magnitude (14 characters), that still allows for an insane amount of communication.

I know I'm going to have multiple modes, eventually, on this thing. Dan's code for tracking amperage and shot notification is too valuable to let go. Being able to put an AEG into a diagnostic mode, and plot out the information into an Excel spreadsheet, is going to be an incredible tool. That code is going to run separate of the display. Just hook the AEG up to the USB port and the computer, and trigger the gun to fire. Dan's code takes care of everything else.

The primary mode I'm going to work on now is the fire control mode.
After every shot, the gearbox needs to send:
Amperage minimum
Amperage maximum
Voltage
MOSFET Temp
Barrel Sensor Shot Detection
Barrel Sesnor Timing
Total Shots Fired (to be compared to shots commanded, for error correction)

That's seven messages. If I double that to 14 messages (for growth), that allows 10 characters per message. If we use three alphanumerics, that allows for 7 characters to encode what the message value is (minus error encoding, if that is needed). Messages are probably going to be either true/false, or ADC readings (voltage/amperage/timings). If the ADC are encoded as actual characters (instead of 512/1024 values) then they'll take 4 characters each. That will allow for three more characters at the end of the message, for growth. I'm pretty sure that this will be enough for priority communications while shots are being fired.

In between, the communications protocol can be much more lax. Very lengthy messages will be able to be sent. The timing won't be critical.

However, with the strict communications protocol imposed, the display will be able to be updated in almost real-time, even during shots. This will give feedback to the user if any issues come up

Does this make sense? Are my assumptions even close?
By dkulinski
#142446
Alright, you are talking about sending fully formed messages to the oLED. Since it has some programming capacity you can devise a way to code your messages, much like a cpu instruction. This requires creating a program on the 4D systems oLED that accepts correctly crafted codes from the Arduino.

So let's talk about serial communication. You are correct on the framing. Technically baud is the incorrect term and it is just bits per second (bps). Parity allows error detection but not correction. This shouldn't be a big concern for you.

Alright, so you need to display certain information. Some of the things you have stated:
  • Rounds fired
  • Amperage upper and lower bounds
  • Temperature
  • Chrono (I am assuming this is what you mean by timing)
  • Error condition
I suspect in a main mode you mainly want to display the number of shots fired and color the screen for error conditions.

Alright, 5 messages so far. To represent this, you can use 3 bits in the serial frame and then the last 5 bits to pass on a data value. Let's define some quick code based off of some binary codes (the N represents the data that could be sent):

0b000NNNNN Round fired - NNNNN (00001 = Round detected by sensor, 00000 = Round didn't trigger sensor)
0b001NNNNN Amperage Upper 5 bits - NNNNN (MSB)
0b010NNNNN Amperage Lower 5 bits - NNNNN (LSB)
0b011NNNNN Temperature - NNNNN (logarithmic approximation of MOSFET temp, only 0-31 can be represented in 5 bits)
0b100NNNNN Chrono Upper 5 bits - NNNNN (MSB)
0b101NNNNN Chrono Lower 5 bits - NNNNN (LSB)
0b110NNNNN Error - NNNNN (error code, up to 32 errors)

Alright, so there are 7 defined codes and associated data. You could split the temp into the same type of upper and lower transmission as the rest of the codes that need a decent resolution. Also certain instructions can expect to packets to complete an instruction. In this case, say amperage, you send the command, the first 5 bits and the next frame contains the last 8 bits.

So you send one of these special bytes through the serial link the 4d systems chip receives and the program on the 4D systems controller decodes and updates the display.

Essentially the code starts to look like this on the Arduino:
Code: Select all
#define RND_FIRED 0x00
#define AMP_H 0x20
#define AMP_L 0x40
#define TEMP 0x60
#define CHRONO_H 0x80
#define CHRONO_L 0xA0
#define ERROR 0xC0

#define CMD_MASK 0xE0

...

void send_serial_comand(uint8_t command, uint8_t data) {
  Serial.write((CMD_MASK & data) | command);
}

...

void loop()
{
  while(1) {
    ... // Do all your work for firing here
    send_serial_command(RND_FIRED,bb_sensor);
    send_serial_command(AMP_H, (amp_reading & 0xF8) >> 5);
    send_serial_command(AMP_L, (amp_reading & 0x1F));
    send_serial_command(ERROR, error_condition); // Maybe an error value of 0 means everything is good
}
The above code is just some thoughts on how to do it. But as you can see, you send 4 bytes for a regular firing setup. Of course the display doesn't know what firing selection the selector switch is in. You could easily add this as an error code (maybe these should be info codes?)

Dan
By Mee_n_Mac
#142456
I think we need to figure out what can be sent in the time available. If you're running a flavor of the diagnostic code that samples the current every 1 msec, then there's only so much time to do all the messaging that uses that 1 msec data. My gut feel ATM is that you'll need to divide up the messages into those that send data to the display in real-time, as it happens and into other message(s) that have less time critical data that can be sent later or stored in Arduino SRAM and sent after the motor has stopped.

Consider that we only got useful current readings when the sampling period went down from 4 to 1 msec. Faster sampling probably isn't needed (nor possible) and slower can't be that much slower (2 msecs perhaps ?). So when firing you've got 1 msec to :
- take the ADC reading (that's about 10% of the 1 msec I think)
- perform the slope and other calcs to see if it's time to stop firing (???% of 1 msec)
- send whatever data to whereever (depends on mesage length and HW vs SW UART)
I'm thinking there's not a lot of time left over after steps 1 and 2. Also consider that the ATmega 328 has only 1 hardware UART. This means either sharing the serial I/O pins between the PC serial comms and the display ... or using a "soft" UART to communicate to the display. The latter is conceptually nice and clean but chews up already limited time. I don't think the NSS routines allow the MCU to dump the serial data to a buffer and then go on doing other calcs. I'm not sure what happens if NSS uses interrupts and the 1 msec interrupt happens.

So how much time in any 1 msec period is being used at present ? I think the working code does some slope detection and starts & stops the AEG as desired ... and also sends ADC data to the PC ?? If this is really all working w/o any hiccups then I'd think there'd be some time to send some data to the display in place of sending it to the PC. The thing is ... it'll be hard to design anything w/o having some idea of what the worst case timing can be. You could code up some messaging but it may be hard to debug if once every so often you run out of time and things get goofy. If you had a simple O-scope or logic analyzer I'd have you set an output pin at the start of the 1 msec interrupt and reset that pin when the slope, etc calcs were done. Perhaps there's a good way to use a timer to measure this period and send it's data out to the PC ?

As far as message definition goes, let me toss an idea into the ring. Why not a 1msec message and a "slow" message (or perhaps several slow message types, one "per shot", one per "XYZ") ? A standard UART type serial link is going to be used as that's what the display has. Stick with 8N1 at whatever bit rate. Use the 1'st byte sent as a message ID/type. The next byte or 2 or 3 or 4 or ... is whatever you define them to be. No need for separate messages for each data type, just put the data in order and you'll know what byte is what when it get's to the display. This saves on overhead, less sending of bits to ID the message and more bits sent devoted to the data. As before start with a simple message sent every shot, like a shot counter. And send the data as binary, not ASCII encoded. Let the display CPU spend some time doing the conversion.

Do you intend to send/save the ADC data to the display every msec or perhaps just some stats of the ADC readings ?
Last edited by Mee_n_Mac on Sat Apr 07, 2012 4:10 am, edited 1 time in total.
By Mee_n_Mac
#142457
StaticDet5 wrote:I'm not completely sure how serial communications work, so I'm going to talk out loud.
I think both systems are capable of communicating at 57600 (56K) baud. Baud refers to the speed at which the system can communicate bits (1's or 0's). We're going with the most common 8,N,1 protocol: 8 data bits, no parity, 1 stop bit.
If I understand correctly, 8 data bits (256 characters) can be encoded in each "data frame". The lack of a parity bit means no error correction in this protocol. If we use a parity bit, we could catch an uneven number of errors (1 corrupted bit being the most common number), but we'd miss even numbers of errors. The stop bit simply tells the system when it is done communicating a "data frame".
This means that at 56K, we have to divide by 8 (or 9?) to determine the number of characters we can send per second. We'll divide by 10, because that makes my head hurt less and gives us a bit of a buffer. That means we can send 5600 characters per second, right?
From the other direction, I think the max number of rounds per second is 30-40 (I haven't heard of a conventional AEG shooting faster than that). If we have 5600 characters to use, and we divide them equally among the 40 shots, that lets us send 140 characters per shot, or roughly one text message per shot. That's awesome.
I think you need to look at these 2 wiki's ...
http://en.wikipedia.org/wiki/Universal_ ... ransmitter
http://en.wikipedia.org/wiki/Asynchrono ... munication

For 8N1 you send 10 bits for each 8 data bits sent. This means if you send 56,000 bits/sec then you only get to send 5600 bytes of data per second or 5.6 bytes (so really only 5) every msec. Quite often those 8 data bits are encoded, as in ASCII encoded. This is used to send characters and such in general. The number 0 would actually be sent as a 0011 0000 (in binary) or a 30 (in hex) and not as 0000 0000. At this point you have to ask yourself is you want to send data as ASCII encoded characters or as straight binary data. To illustrate let's say you had an ADC reading of 723 counts. Leaving it as characters that's 3 data bytes; a 7, a 2 and a 3. The 8 data bits for each would then be 0011 0111, 0011 0010 and 0011 0011. Compare that to sending the 8 bits unencoded. The ADC outputs 10 bits with 00 0000 0000 = 0 counts and 11 1111 1111 = 1023 counts. Since it is 10 bits and the serial comm is working with 8 (data) bits, you'll need to send 2 bytes (vs the 3 above). You can decide how to split up the 10 bits and "pack" them into the 2 bytes. Obviously 2 bytes is less than 3 bytes if you're limited to how many bytes can be sent.
By StaticDet5
#142464
When I first went back to this project, in December or January, I looked at using Avenue33's code. There were a couple of issues.
First, his library hadn't been updated for use with Arduino 1.0, and required a hodge-podge of NewSoftSerial and some modification of other libraries. I couldn't get things to work, and I couldn't get help getting them to work (I'd been told three times "Use the new library").
Second, Avenue33's library (the last I looked at it) allowed you to drive the display completely from the serial port. Screen rendering, data storage, everything, all would be done by the Arduino, with no real usage of the uOLED's on-board processor. I think that's the big trick for this project: Have a gearbox computer that drives "AEG Stuff" and a display computer that drives the user interaction other than the trigger.

Image
https://lh4.googleusercontent.com/-NAfU ... 2Bcopy.jpg

Here's where I want to get the tactical display, eventually.
I'd like the display to be as innocuous as possible. There when you want it, able to yell at you if it needs to, but other than that, quiet.
If you need more information, you can look a little harder at the display, and it's available. If you need detailed information, you're going to jump into a higher level of interaction with the computer (Hands off the trigger and selector).

The data that needs to be updated, on the fly, is really represented by the four quadrants. You're not going to change your fire mode in the middle of firing.

(I just noticed that the FPS value is seriously in error).

All of the data is accompanied by a small relative status indicator. This will give a level of situational awareness beyond a simple number. It's designed to give you some idea of how close you are to your pre-established limits. Hitting a warning threshold will trigger some kind of notification. Hitting a critical threshold will change the behavior of the AEG (Under-volting will shut off the gun. Spiking the temperature will lock out the firing circuit. I have a neat idea for the low mag critical event, I'm saving that until I have a chance to test it). All of these behaviors will be user definable through the programming code. I'm hoping I can define the behaviors through "Code-Blocks", to let the user "pick and choose" the behaviors they want for their AEG.

Back to the points you guys made:

I think I've gotten my head around the use of binary. I'm having to go down mental levels of abstraction, but I'm getting it.
If I'm reading Dan's point correctly, and I understand the serial protocol correctly, should we break the message up into two bytes, minimum? First for the message type (Amperage Min/Max, Voltage, Temp, etc), with the second byte being the encoded value? Doesn't your system require two packets anyway (A 5 bit frame and an 8 bit frame)? I'd like to have more room to send different messages, and a "unified protocol" to send the messages, whether the gearbox is firing or not. Right now, the display is not really going to be able to tell when the gearbox is firing. It doesn't need to. It just takes the information, processes it, and serves it to the user.
Looking at the "Round Fired" suggestion you posted, wouldn't it be better to have the "Round Detected" read "11111" and "No Detection" read "00000"? This method gives "Five degrees of certainty" and would also be able to give an indication of noise on the line (Any "Round Fired" packet without all 1's or 0's would still give us the information we really need, and tell us something else as well).

Dan's testing code sent two pieces of information, every millisecond, down the serial link. We don't need to send that information every millisecond. We need to send it at the summation of every shot. The Arduino needs to look at that information, but the processing is done locally, and the decisions to keep cranking the gearbox are all local.
Once the gearbox has registered a completed cycle, it sends off the needed information to the display. My understanding is that the serial port is buffered. It takes less time to write to the buffer than it takes to send it. That works for us because the sent information isn't "gearbox critical", and the gearbox can continue doing it's thing. If each shot, on average, takes 20 milliseconds (That would be 50 shots per second), that still gives us an insane amount of time to send what we want to send.
I don't see a reason to send data every millisecond (or any other period of time), except during a diagnostic mode when we really only care about what is happening in the gearbox (This is Dan's earlier code that generated the spreadsheets after I learned how to us PuTTY). If we just send it at the summation of every shot, it's fine. Outside of a firing sequence, I'd have the gun do periodic checks on the status (Temp, voltage, etc), but those aren't critical.

I'll try to get a flowchart up of how the two processors are interacting. I think that will help.
By Mee_n_Mac
#142469
StaticDet5 wrote:I don't see a reason to send data every millisecond (or any other period of time), except during a diagnostic mode when we really only care about what is happening in the gearbox (This is Dan's earlier code that generated the spreadsheets after I learned how to us PuTTY). If we just send it at the summation of every shot, it's fine. Outside of a firing sequence, I'd have the gun do periodic checks on the status (Temp, voltage, etc), but those aren't critical.
That will certainly help but you may not have as much time as you think. Afterall what's happening ... you've got a single core MCU that does all the calculations. There's calcs being done every msec. If ... say ... 40% of every msec is used getting an ADC reading and doing those calcs, then you only have 60% of the shot-shot time left for other/message processing. That should work out OK, probably will, but that "background" code needs to be able to be interrupted by the 1msec code. Some processes handle that better than others. In particular if you have multiple interrupts running and 2 overlap, then you've got to be a little careful. I'd be worried about using the NSS "soft" UART for communication to/from the display. If you end up using the hardware UART, I think you'll be fine. It has a buffer and can do all the timing for bit transitions as the serial data gets sent, completely independant of the 1msec (or other) interrupt running. The only thing with this is that those same serial Tx/Rx lines are shared with those going to the USB connection to the PC. Not an issue when the Arduino is in the AEG all by itself but your display processor will see all the traffic when you're uploading a sketch or sending serial data to the PC. Since your display is smart it should be able to ignore the "bad" messages. I think. :mrgreen:
By StaticDet5
#142481
I don't think it's that smart... When I first started playing with it, I had issues with programming the Arduino with the display attached. I think I may have to get a DPDT switch, something that disconnects the display when the USB connection needs to be active. That will solve a lot of problems and only increase the electrical complexity very slightly. We won't be able to use the serial port to debug, once the display is hooked up. I've definitely needed that crutch, so far. I'll have to get creative in my troubleshooting.

Dan, you were absolutely right about the Futurelec components. I put an order in for resistors, capacitors and some headers/cable pins. It took a little while to get here, but it's nicer stuff than I anticipated. This is going to make cabling much easier.

I'm going to try to play with the serial signaling this week. I didn't get anywhere near as much done today as I hoped. Real life interfered. Again. Stupid real life... :)
  • 1
  • 24
  • 25
  • 26
  • 27
  • 28
  • 32