Show Posts
Pages: 1 ... 53 54 [55]
811  Using Arduino / Programming Questions / Re: Potentiometer Code Question on: September 12, 2011, 12:23:03 am
Are you using the Serial as the interface to the computer? If so, it runs at a significantly lower rate than MIDI -- IIRC, MIDI runs at 32 kbps or so.

If the Serial class is blocking (which I think it is?) then there is no risk that you will "flood" the MIDI wire with more than it can "take." However, as already suggested, you should check what the last value sent was, and only send a new value if the value read is different from the previous value.

Another useful mechanism is to use a time step. Remember when last you sent a message, and only send a message if X time has passed (say, 10 milliseconds).

So, something like:

Code:
unsigned long lastTime = 0;
unsigned int lastValue = 0xfffeU; // force a send initially

void loop()
{
    unsigned long now = millis();
    if (now - lastTime >= 10) {
        unsigned int value = read_and_calculate_your_value();
        if (value != lastValue) {
            lastTime = now;
            lastValue = value;
            send_midi_controller_bytes(value);
        }
    }
}
812  Using Arduino / Programming Questions / Edge triggered interrupts -- can they be lost? on: September 12, 2011, 12:17:04 am
If I use the interrupt mode rising, falling, or changing, is there any chance of the interrupt being lost?
For example, if interrupts happen to be turned off right when the change happens, will the interrupt be queued, or will it be lost?
Also, is there a good way of blocking and re-awakening the loop() function, while still allowing interrupt handlers to execute?
Specifically, I'd like to "kick" the loop function in response to the rising edge of an input square wave (from a timer chip) tied to pin 2, and also on the user pressing any of my 4 input buttons (I'll have to rig some logic for this to generate a change on pin 3).

Here's the pseudo-code I want:

Code:
void int_pin_2()
{
    interrupted = true;
    source2 = true;
    kick_main_loop();
}

void int_pin_3()
{
    interrupted = true;
    source3 = true;
    kick_main_loop();
}

void loop()
{
    int sources = 0;
    if (!interrupted) {
        wait_for_kick();
        uint8_t sreg = SREG;
        cli();
        if (source2) sources |= 1;
        if (source3) sources |= 2;
        source2 = source3 = interrupted = false;
        SREG = sreg;
    }
    do_stuff(sources);
}

This is pseudo-code, but I hope the intention is clear. If this were running on battery, a low-power state in wait_for_kick() would save battery, although "power off" is not needed -- this will actually run on wall wart, and I'm only trying to write code the way I feel it "should" be written.

Speaking of which: is this structure even a useful desired on the AVR? Is it worth it trying to "do nothing" when I know nothing is happening? Or should I just run loop() full bore and it won't harm or wear out anything? (Assuming I don't actually do anything other than return if there is no input).
I guess a third option is to put in delay(10) in the main loop, rather than wait_for_kick(), but that would increase my worst-case interrupt latency a smidgen -- again, probably doesn't matter for this application, but I don't want to go with "dirty" habits.
813  Using Arduino / Programming Questions / Re: How to put a comma ( , ) on 1,000 printing on 16x2 LCD...?? on: September 12, 2011, 12:03:23 am
I'm also playing around with a 16x2. It looks to me as if that code really should print 1,001 for the value 1001. It does the wrong thing for exactly the value 1000, though, and probably the wrong thing for any negative value (haven't verified it).

Here's an alternative version:

Code:
// Does not work right for exactly the value -32768!
void printWithComma(int val)
{
    if (val < 0) {
        val = -val;
        lcd.print("-");
    }
    if (val >= 1000) {
        int v = val / 1000;
        lcd.print(v);
        lcd.print(",");
        val = val - (v * 1000);
        char buf[4];
        sprintf(buf, "%03d", val);
        lcd.print(buf);
    }
    else {
        lcd.print(val);
    }
}

It assumes there's a global named "lcd" to do the printing. Just paste this in your sketch after you declare the lcd, and before your setup or loop function, and call it to print the value -- it should work just like you want it for all 16-bit integer values except -32768.
Pages: 1 ... 53 54 [55]