SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By dkulinski
#142509
Sorry I didn't contribute today, I was working on laser tag. In fact I was fighting with an hd44780 display. I need to solder up the other prototype to see if I blew the display on this prototype. It initialized once but no more.

As for the serial coding change is anyway you please. Not a lot of thought went into the code I posted, consider it drawing on a napkin.

Mee_n_Mac is correct about processing time, but it think you are right about the frequency in which you need to send data. If you only transmit after each shot or X number of seconds you will have loads of time. Really the adc reads are probably your most frequent and expensive code..

Dan
By Mee_n_Mac
#142757
A thought came to me from to another thread in that you could use an analog input to sense a digital switch input, in particular for the trigger switch. Why do this ? Because with a little careful analog choices of Rs and Cs and some software, you can debounce the switch without using a delay or multiple samples or ... What you'd do is set a threshold of ADC counts to determine if the switch has been pushed or not. Once past that threshold the software can change the "unpush" threshold to be a very different value (same as a Schmitt trigger). A little analog filtering (adding some caps to the circuit below) can ensure that any bounce can't get past that revised threshold.

Just a thought while it was on my mind.
AnalogButtons1sml.jpg
Note the above was used to implement 2 switches on a single line but an even simpler circuit could be used to implement just a single switch.
You do not have the required permissions to view the files attached to this post.
By StaticDet5
#143015
Sorry about the lack of posts. I've been puzzling the serial sending and receiving without huge success (but some small minor successes). Also, it looks like I'm going back to real work (Another 6 hours of waiting to see if everything is holding together).

Is there any kind of timing disadvantage to using an analog trigger pin? It will make a progressive trigger implementation simpler (that's going to be an eventual option, but not something I'm going to mess with until the basic on/off trigger is fixed). Hell, what are the disadvantages to the analog trigger? I think I've got room for the analog trigger, and the advantages to it are huge (this will allow the die-hard AEG guys to set a trigger break).

I've changed my approach, somewhat, but I want to pick your brains on things.
One of the things that really pushed the project forward, quickly, was the data presentation. Something simple like incorporating a "special character" in the Amperage Report allowed us to quickly and easily get two pieces of information (and infer a third) into an Excel spreadsheet.
When I set up the Arduino for the end of shot data report, can I keep that same tab-spaced format, and then use an "end-of-line" character to signify that the shot has ended?

I'm thinking about pre-defining each message as an array. The header byte identifying the message type, a predefined number of bytes after that to contain the message (Raw ADC value is going to be the typical filler), and then a "tab character". Is that the right way to do it?
By StaticDet5
#143016
I'm working on getting better information about interrupts (Dan, I hate to keep pestering you about it, but you're a guru in this area).
I need to leave digital pins two and three free for interrupts, correct?
By Mee_n_Mac
#143017
StaticDet5 wrote:Is there any kind of timing disadvantage to using an analog trigger pin? It will make a progressive trigger implementation simpler (that's going to be an eventual option, but not something I'm going to mess with until the basic on/off trigger is fixed). Hell, what are the disadvantages to the analog trigger? I think I've got room for the analog trigger, and the advantages to it are huge (this will allow the die-hard AEG guys to set a trigger break).
An A/D conversion takes a "long" time, something a bit longer than 100 usec IIRC, so that's more time than to read a digital pin. Does that time have any significance on what you're doing ? Maybe, maybe not. Obviously if the loop() is doing not much but reading the A/D looking for a trigger push, it won't have any significance. Now if you're sampling the A/D to read the current every 1 msec, it may have. Out of that 1000 usec you're already using 10% to read the current. Then you'll be doing some calcs on those readings, making a running average, looking for dips, etc. Do you have enough time left over to add in another 10% or so to read the trigger ? At this point I just don't know. I guess so long as you have enough time to do all that needs to get done it doesn't matter if you've got 1 spare usec or 10.
By Mee_n_Mac
#143019
StaticDet5 wrote:I've changed my approach, somewhat, but I want to pick your brains on things.
One of the things that really pushed the project forward, quickly, was the data presentation. Something simple like incorporating a "special character" in the Amperage Report allowed us to quickly and easily get two pieces of information (and infer a third) into an Excel spreadsheet.
When I set up the Arduino for the end of shot data report, can I keep that same tab-spaced format, and then use an "end-of-line" character to signify that the shot has ended?

I'm thinking about pre-defining each message as an array. The header byte identifying the message type, a predefined number of bytes after that to contain the message (Raw ADC value is going to be the typical filler), and then a "tab character". Is that the right way to do it?
The thinking is that you'd perhaps copy the message(s) coming from the Arduino to the Display to the display's SD card ? And by using some Excel friendly message format make it easu to read that data off the card and into Excel (or similar) ? I'd say you can do the above. If the fastest rate you'd send a message is at the end of a shot, there's no reason not too.

As for message formatting, a lot depends on the data to be sent. If you're using a standard type of serial comm, then everything will go across as 8 bit bytes. If your data is already in bytes that makes things easy. If your data is in 10 bit chunks, you'll have to decide how to divide and pack it into a series of bytes. And you have to decide whether to send that across as ASCII characters or leave it as binary. ASCII will be Excel readable but require more processing at the Arduino end and perhaps at the display end too. Then again that'll probably be part of the serial.write routine you'd call to send the data so perhaps it's easier to use ASCII than not. Insert a tab character between each piece of data and a carriage return as an end of message delimiter ? This way the message can be variable in it's byte length even as it's content is defined.

IE - Header, tab, ADC reading, tab, shots fired, tab, etc, tab, etc, tab, CR

If all the above is in ASCII, the message will be long but easy to format and interpret at the receiving end (by looking for and counting the tabs). Just to point out that the ADC reading might be a 1 or a 1000, 1 byte to send or 4 bytes to send, but so long as the reciever knows the 2'nd data item is the ADC reading and there will be a tab in front and behind, it should be able to count tabs and interpret the data sent.
Last edited by Mee_n_Mac on Tue Apr 17, 2012 1:21 pm, edited 1 time in total.
By StaticDet5
#143020
I'm working right now to get the display to read the serial line and display the data. I'm having a fair amount of difficulty with that, even though it should be a pretty easy program. Once I can read and display the serial data consistently, I'll have the display working very quickly. I just keep banging my head against the wall with the serial reads...
By Mee_n_Mac
#143027
If I may recommend a simple course of action ... "can" a message from the Arduino that you can send with a push of a button. Use a special Arduino build of software to get the link working, put aside the working AEG build of software. The message should be something like 1, 2, 3, ... so it's easily recognized as working or not at the display end. For that matter confirm the Arduino is sending out what you think it is by doing a wrap-around test. If you're not using the same Tx/Rx pins for the display that are used for the USB/PC serial monitor, you can connect the Tx to Rx and "print" whatever message is being received by the Arduino from the display ... which in this case will be the message the Arduino sent out.

At the display end ... I dunno. My inclination would be to have the message displayed and to have the display processor send the message back to the Arduino so you could know (via the PC serial monitor) it was received even if it didn't get displayed properly. Consider it a slightly longer wrap-around test.

Now IIRC you were planning to use the same Tx/Rx pins for the display as are used for the USB interface. In the working AEG build I think that's a good idea due to the freedom the hardware UART gives you when the 1 msec interrupt will be running. But I wonder if, just to get the Arduino talking to the display and to get the display ... ahhh ... displaying, if it wouldn't be easier to use a software serial port and a different set of pins. Predefine a set of messages you can send from the Arduino and use the Arduino as a "test bed" to get the display functional. Then figure how to integrate the now working display with the working AEG build of software via the HW UART. Having the serial port as a debugging tool may prove to be of some use and thus worth the extra effort to learn soft serial stuff.
By StaticDet5
#143062
Right now I'm using a modified AnalogSerial arduino program to send ADC messages on the serial line. I thought I had good code yesterday, but all I drew was the "screen box". Nothing (garbled or otherwise) came through.

I think the analog line on the trigger is a good idea. Even better is implementing a jumper system so that the trigger can either be used with your resistor network, or as a plain digital line. This way, if the speed does become an issue, the electrical layout is unchanged.

Back to grinding away at this display.
By StaticDet5
#143070
Just stepped out and saw the shuttle. My heart feels kinda pulverized right now. Everything lined up: Break in the trees, ray of sunshine, beautiful shuttle Discovery gleaming white...

I had a breakthrough with the display. I was making things too complicated. I'll probably have to go back to complicated at some point to take advantage of the full benefits of the serial port.

Crap. It WAS working. I just got done rebooting, and now it's not behaving correctly. Hmmm...
By StaticDet5
#143077
Annnnd.... the worst result in science: inconsistent results.

But they're results.
Code: Select all
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3);

// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin = A5;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
//int sensorArray[] = {1,0};         // array to store the sensorValue
//int outputArray[] = {2,0};          //array to store the outputValue
String sensorString = "10";          //string to store the sensorValue
String outputString = "20";          //string to store the outputValue


void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(115200);
  mySerial.begin(57600); 
  
}

void loop() {
  // read the analog in value:
  sensorValue = analogRead(analogInPin);            
  // map it to the range of the analog out:
  outputValue = map(sensorValue, 0, 1023, 0, 255);  
  // change the analog out value:
  //sensorArray[1] = sensorValue;
  //outputArray[1] = outputValue;
  
  sensorString[1] = sensorValue;
  outputString[1] = outputValue;
  analogWrite(analogOutPin, outputValue);           

  // print the results to the serial monitor:
  //Serial.print("sensor = " );                       
  //Serial.print(sensorValue);      
  //Serial.print("\t output = ");      
  //Serial.println(outputValue);
  
  //Serial.print(sensorArray[0]);
  //Serial.print(" ");
  //Serial.print(sensorArray[1]);
  //Serial.print("\t");
  //Serial.print(outputArray[0]);
  //Serial.print(" ");
  //Serial.println(outputArray[1]);  

  Serial.print(sensorString);
  Serial.print("\t");
  Serial.println(outputString);
  mySerial.print(sensorString);
  mySerial.print("\t");
  mySerial.println(outputString);

  // wait 500 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(50);                     
}
This is the Arduino code


Eventually, I want the Arduino to send out two packets of information: A message identifier and the message "text" itself (Yeah, this is what we've been talking about for a week, but I'm just talking out loud here). The message identifier is one byte long. Anything less and it takes up the same amount of room (right?). The message "text" itself may be multiple bytes long. The entire message will be tab-separated and carriage return (new line? same thing?) terminated.

I need to get the display to show the data in this format (Message ID-tab-Message Text-NL). Then I'm going to have the display start message slicing to put the right information in the right places on the display. Finally, I'll have the display start storing messages on the onboard uSD card (the current card is 16GB. I think we have space).


Below is the code for the uOLED Display. This IS NOT ARDUINO CODE.
Code: Select all
#platform "GOLDELOX-GFX2"

/*
Serial display for the airsoft smartgun developed by StaticDet5
This program takes the serial input and displays it to the screen
Tested:
4-17-2012   Program appears to display the correct symbols
*/


#inherit "4DGL_16bitColours.fnc"

var combuf[8];
var j;
var chr;

func main()




    gfx_Set(OUTLINE_COLOUR, DARKOLIVEGREEN);
    gfx_Cls();
    txt_Set(FONT_ID, 0);
    txt_MoveCursor(0,1);
    setbaud(BAUD_57600);
    com_Init(combuf, 16, 0);

    repeat
    gfx_Set(OUTLINE_COLOUR, DARKOLIVEGREEN);
    //gfx_Cls();
    j :=0;
    txt_MoveCursor(3,1);
    putch(combuf);
    chr := serin();
    txt_MoveCursor(3,1);
    putch(chr);
    /*while ( (chr := serin()) >= 0)
            txt_MoveCursor(3,1);
            putch("                ");
            txt_MoveCursor(3,(1+j));
            putch(chr);
            to(COM0); putch(chr);               // send buffered chars to com port
            j++;
    wend
    */
    //pause(100);
   forever


   endfunc



The code is really there because I'm talking out loud. Someone else coming behind me can see where I'm making mistakes.

I think the problem with displaying the entire message is in the display code. I only have it pulling the first character from the serial buffer. When I had it trying to iterate over the buffer, it wasn't displaying anything. That's the "While" section that is commented out.

However, this code is displaying character changes that correlate to the changing pot on the Arduino serial test. I just need to get a little further.
By StaticDet5
#143081
GOT IT!

The Arduino code remains the same. The code below is the revised display code. Once again:
THIS IS NOT ARDUINO CODE!
Code: Select all
#platform "GOLDELOX-GFX2"

/*
Serial display for the airsoft smartgun developed by StaticDet5
This program takes the serial input and displays it to the screen
Tested:
4-17-2012   Program appears to display the correct symbols
*/


#inherit "4DGL_16bitColours.fnc"

var combuf[8];
var j;
var chr;

func main()




    gfx_Set(OUTLINE_COLOUR, DARKOLIVEGREEN);
    gfx_Cls();
    txt_Set(FONT_ID, 0);
    txt_MoveCursor(0,1);
    setbaud(BAUD_57600);
    com_Init(combuf, 16, 0);

    repeat
    gfx_Set(OUTLINE_COLOUR, DARKOLIVEGREEN);
    //gfx_Cls();
    j :=0;

    //chr := serin();
    //txt_MoveCursor(4,1);
    //putch(chr);
    while ( (chr := serin()) >= 0)
            //txt_MoveCursor(3,1);
            //putch("                ");
            txt_MoveCursor(3,(1+j));
            putch(chr);
            //to(COM0); putch(chr);               // send buffered chars to com port
            j++;
    wend

    //pause(100);
   forever


   endfunc
The display now shows two distinct messages.
The first message has a "1" in front of it, with the character immediately after it corresponding to the position of the Arduino Pot.
The second message has a "2" in front of it, with the character immediately after it corresponding to the mapped value of the Arduino Pot.

The issue comes down to consistency. The values sweep when I turn the knob, but they are not consistent at the extremes (when I turn the pot, and leave it, at one extreme or the other). The values stay nice and fixed, but not always on the same character. I need to figure out if this is due to the limitations of the system, or due to my code.
By Mee_n_Mac
#143082
StaticDet5 wrote:GOT IT!
The issue comes down to consistency. The values sweep when I turn the knob, but they are not consistent at the extremes (when I turn the pot, and leave it, at one extreme or the other). The values stay nice and fixed, but not always on the same character. I need to figure out if this is due to the limitations of the system, or due to my code.
If I'm understanding the scenario correctly, you're getting the expected answer except at the limits of the pot motion ? If so don't worry about it, you've got other fish to fry. Pots are often odd at the ends of their travel. You may be getting an inconsistent short or open. No need to be TS'ing pot problems.
By Mee_n_Mac
#143111
StaticDet5 wrote:I'm working on getting better information about interrupts (Dan, I hate to keep pestering you about it, but you're a guru in this area). I need to leave digital pins two and three free for interrupts, correct?
Pins 2 and 3 are the "direct" external interrupt lines. When something happens on either of these (depending on how you set the interrupts up) an interrupt service routine (ISR, just another function/subroutine/whatever you want to call it) will run. There can be one ISR for pin2 and a separate ISR for pin3. If you never need an external interrupt, you can use these pins just like any others. Now if I understood Dan's earlier explanation, pretty much all the other digital pins can be setup to also cause an interrupt BUT there's some limitations to using these relative to pins 2/3.

- there's no indication of what pin caused the interrupt. In order to find out which pin, the ISR that runs has to read the port(s) and figure out what changed. That in turn implies the signal causing the interrupt hangs around (persists) long enough to be read. A very quick pulse might cause the interrupt and be gone before the code can figure out who caused it. Depending on your usage, this may or may not present a problem.

- I don't see any way, sticking strictly to the Arduino commands, to code for this "interrupt on pin change". Now you can add a C/C++ slice of code but you have to go beyond simple Arduino-land to do it. No big deal but it's some effort. I believe there are some library functions that can be used to do do PCINTs so perhaps it's been done for you.

http://arduino.cc/playground/Code/Interrupts
  • 1
  • 25
  • 26
  • 27
  • 28
  • 29
  • 32