Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Interfacing / Re: Reading Arduino Sketch Flash Memory Using PC? on: September 02, 2010, 02:43:37 pm
Quote
I'm not sure that they are necessary, since there is so little you can do with the hex data you get off the chip, anyway.
Well, you can just clone the hardware, burn another arduino and get an exact copy of the original.

But, after all, Arduino is an open source project, both hardware and software, wouldn't be a bit unethical get money from a derivative project while closing sources? I mean, you could make money and keep it open as the creators of Arduino do.

Just 2 cents.
2  Forum 2005-2010 (read only) / Interfacing / Re: midicontroller on: March 09, 2010, 04:29:24 pm
Here, this is the code to get midiclock from hardware.

From http://www.midi.org/techspecs/midimessages.php
11111000: Timing Clock. Sent 24 times per quarter note when synchronization is required (see text).

That means
- sampling the blinking led
- compute an interval with the previous sample
- update the frequency of a simulated timer (you cannot use the internal watchdog because of its insufficient resolution)
- fire a timing clock event each time the internal clock hits the bpm/24

The loop must be kept tight to get a good precision.
I didn't tested it with a true led, I don't know if there will be the need of a resistor or capacitor because the analog inputs are high impedance and noisy.

You must configure the maximum voltage you'll read from wires (likely 2V).
You can change a divider factor which defaults to one blink per bar.

Code:
//////////////////////////////////////////////
// hw synced midi clock generator
//////////////////////////////////////////////

// which input port is connected to the led power supply
const int ANALOG_INPUT_PIN = 0;      

// tension used to power the led
const double NOMINAL_VOLTAGE = 2;      
const int FULL_SCALE_VALUE = 1023 * NOMINAL_VOLTAGE / 5;      

// threshold, half the voltage
const int HALF_SCALE_VALUE = FULL_SCALE_VALUE / 2;      

// assuming the led will flash on the stomp-box on every bar at 4/4
// i.e. at 120bpm will flash every 2 seconds
// if you wanna change the unit of measure then change LOOP_QUARTERS accordingly
const int LOOP_QUARTERS = 4;      

// the midi clock message
const byte MIDI_CLOCK = 0xf8;      

// previous state of input led
boolean last_state;

// time stamp of the last detected beat
unsigned long last_beat;

// µs to wait before next midiclock
unsigned long interval;

// event to check for
unsigned long next_midiclock;

void setup()
{
    Serial.begin(31250);
    last_state=false;
    last_beat=micros();
    next_midiclock=0;
}

// if you need to add stuff inside the cycle you'll have to make sure to keep its duration
// as short as possible to get a reasonable steadiness
// example: at 120bpm = 48ticks/s = one tick every 20.83ms
// if you want a 5% of precision you must stay within 1.04ms
void loop()
{
    int value;
    boolean led_state;
    unsigned long time_stamp;
    unsigned long beat_duration;
    double bpm;
  
    // needed in several computations
    // (every 70 minutes a hiccup, read specs)
    time_stamp = micros();

    // read tension
    value = analogRead(ANALOG_INPUT_PIN);

    // this threshold will discrminate the on/off state
    led_state = value > HALF_SCALE_VALUE;
    
    // if a beat is detected
    if (led_state && !last_state) {
        // in µs
        beat_duration = (time_stamp - last_beat);
        last_beat = time_stamp;        

        // from µs to bpm
        bpm = LOOP_QUARTERS * 1000000 * 60 / beat_duration;

        // computes next frame in µs
        interval = 1000000 / (bpm / 60 * 24);
        
        // force a fire on beat detection
        // cures also micros() wrap-arounds
        next_midiclock = time_stamp;
    }
    
    last_state = led_state;

    // if limit is reached
    if (time_stamp >= next_midiclock) {
        // fire the midi clock
        Serial.print(MIDI_CLOCK, BYTE);
        
        // recomputes next frame
        next_midiclock = time_stamp + interval;
    }
}
3  Forum 2005-2010 (read only) / Interfacing / Re: midicontroller on: March 05, 2010, 03:34:52 pm
Quote
it is some boss delay and a very old boomerang loopsampler. they have no midiout.
Sorry, I don't get what is hooked to what. May you explain better how things should be connected via MIDI?

Quote
i could find the leds on the printboard an built some dc output from that and connect some relay or stuff to it
Yes, using the led power would be a little more responsive and robust than an opto solution, assuming that you'll have to drill the delay box.
You'll have to connect the led power to an analog input of Arduino. I think you should use both poles, and check before hooking not to trespass 5V.
Anyway I'm not that expert in hw, better you ask around.

Quote
i tried to "merge" the code with some other example in which the arduino reads 6 sensors to midiout.
as is say at this point it is still confusing.
in the second example it worked without #include "MIDI.h"
so i understand that pitchbend is a different type of message.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1165833586
I think you should make a clear statement about your project requirements. Then you could ask for how to implement the functions you need.

Quote
what is "i" in the loopfunction?
It's a variable used as an index to access each element of the last read values array.

Quote
where is the midichannel set?
const byte MIDI_CH = 1;

Quote
where  would pitchbend message and send its value go in?
Now, that's exactly what I'd like to know..
4  Forum 2005-2010 (read only) / Interfacing / Re: midicontroller on: March 04, 2010, 05:29:58 pm
Hi, reading a second sensor would basically consist in replicating all the global data structures and instructions included in the loop() function, specifying a different analog input port and a different midi message.
You could go with some like a copy and paste way, but it would be better reorganizing the code in a more organic way, for example with parametrized functions.
That's missing from my code because it is an example, not a complete program.

Code:
int sensorPin = 0;
is pointless unless you use that variable elsewhere in the code.

Maybe you wanted to add something like
Code:
values[OVERSAMPLE-1]=analogRead(sensorPin);
the program behavior wouldn't change however, only a readability thing.

I think the led/fotoresistor idea is a bit awkward for several reasons, you could check if there is some alternative way to do it.
Is your digital delay capable of midi in or out?
If so you could try to see if it's capable of syncing some midi clock in or out with the rest of the gear.
Which specific model of delay are you using?
5  Forum 2005-2010 (read only) / Interfacing / Re: battery power for ardweeny or RRRRRRRBBA on: January 23, 2011, 10:00:47 am
If your paramount objective is power saving, then using a voltage regulator will worsen things because it will suck energy while cutting the extra voltage (and it won't either augment voltage when battery are low, obiously).
If you look at the specs here:
http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf

you'll find this meaningful diagram that shows how the 328 can be run from 1.8V to 5.5V:

In order to decide if your project can cope with low voltages, you'll have to consider these facts

Pros
- running at a lower voltage will draw much less and extend battery life (running at 3V instead of 5V means kind of 3x improvement) .

Cons
- analog inputs will use supply voltage as reference
- all outputs can't go over the power supply voltage
- you have to run slower, ex: 2.7V=8mhz and you have to consider battery voltage decreasing with time (alkaline voltage drop is very steep, nimh and lithium are better) anything in the range 3V-5V might be reasonable.
- clock frequency won't be precise, consequently all time related functions as well.
(the latter two points might need code compensation)
- peripherals will get at max power supply voltage.

If your project can manage the cons you'll have a larger choice of battery options.

6  Forum 2005-2010 (read only) / Interfacing / Re: ultrasonic sensor + real time clock question on: March 15, 2010, 04:01:51 pm
I think there are two aspects of your problem which seem to overlap.
Putting Arduino on sleep mode would mean putting the processor in a stopped state to reduce current drawing.
Anyway all the other components (RTC, wave shield, solid states on the board) would continue to absorb, maybe more than the processor itself.
You could then programmatically exit from the sleep state by mean of the internal watchdog timer which runs indipendently from the core.

Here is a complete example.
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/

Beside that, maybe you wanted only to understand how to program an algorithm to activate or not a certain behavior according to the time of the day and that basically could be done with an if inside the loop.
The tricky part is that that means comparing the RTC with some constants, and because time from the RTC comes in "slices" (y m d h m s) you'll need a
 way to assemble and compare them as a whole, (well, in your case only hours and minutes).
Assuming that you are already reading from the RTC then this would be accomplished by something like

Code:
// boundaries, these won't change
const int start_time = 22 * 100 + 30;
const int end_time = 7 * 100 + 30;

// variable declaration
int current_time;

// a whole value to compare with
current_time = hours * 100 + minutes;

// inside the boundaries?
if (current_time >= start_time || current_time <= end_time) {
    if (something_happens) {
        // duty now..
    }
}

I didn't tested it, it comes without any guarantee.. :smiley

You may want also to give a try to this library and related examples.
http://www.arduino.cc/playground/Code/Time

Let me know if that's clear enough  smiley
7  Forum 2005-2010 (read only) / Interfacing / Re: MIDI lib code help on: February 10, 2010, 01:07:59 pm
When you write in the Arduino language you are actually programming in C++, an object oriented language.
Its syntax can be quite quirky compared to Basic for example, but the developers of the Arduino system needed a down-to-the-iron compiled language to fit in such a tight environment (16000 bytes).
They made however also a valuable effort to simplify the life in the building process, hiding some tedious details in the IDE.
OOP is built on the definition of classes and instances of classes.
You can think of a class as a cookie mould, and the instances (objects) as just the cookies.
Classes define properties (variables) and methods (functions) that you can access via the "." operator on the objects originated from the classes.
For example: you could create an instance of the cookie_class (a class name) called cocoa_cookie (a variable name for an object) and then operate on that object thru the properties and methods which were defined in the originating class.

// an instance, object creation
cookies_class cocoa_cookie;

// access to a string property
cocoa_cookie.special_ingredient="Cocoa";

// access to a boolean property
cocoa_cookie.powdered_sugar_topping=true;

// access to the method cook (minutes, celsius)
cocoa_cookie.cook(20, 180);

// access to the method eatme(who)
cocoa_cookie.eatme("Cookie Monster");

Actually, much of the code you see in examples uses already existing instances and almost never creates classes, but you could do it in the .pde if you liked.
Libraries use much more OOP to "wrap" methods around specialized themes.
As how the libraries in Arduino are made, usually the library's developer has already created an instance of the object you need to cope with. In case of the midi library you have the instance "MIDI", so you can invoke MIDI.sendNoteOn(note, vel, chan); method to send a noteon message.
Strangely enough that library lacks a method to wrap the pitch_bend message, which with Arduino would be very appropriate if you want to thereminize a synth.
I made this little program to implement it, if you want to check it out then:
- set your pitch bend limits on the synth to -24/+24 (you'll have 4 octaves)
- adjust if necessary the MAX_SENSOR_VALUE const
- adjust the smooth factor OVERSAMPLE (to reduce sensor noise and micro movements)

Regards

PS: while testing, if you ever notice squeals, sparks, smoke or bad smell coming from the synth, then leave the room really really fast!

Code:
//////////////////////////////////////////////
// a midi pitch bend implementation
// with noise smoothing
//////////////////////////////////////////////

#include "MIDI.h"

const byte MIDI_CH = 1;      

// how many sensor samples are taken to compute the average
// the accelerometer is quite noisy
const byte OVERSAMPLE = 50;
const byte PITCH_BEND = 6;      

// the max value you can expect from the sensor you are using
// it depends on many factors, which sensor, which tension applied,
// which reference configuration on Arduino, etc..
const int MAX_SENSOR_VALUE = 600;      

// mobile average samples array
int values[OVERSAMPLE];
int last_average=0;

// the missing function in midi library
void midi_pitch_bend(int value, byte channel) {
    byte lsb;
    byte msb;
    
    lsb = value & 0x7f;
    msb = value >> 7;
    MIDI.send(PITCH_BEND, lsb, msb, channel);
}

void setup()
{
    const int n=41;

    // If you wanted a slightly better resolution from the sensor, you might connect
    // the 3.3v pin to aref pin and uncomment the following instruction.
    // but read the warning here before hacking: arduino.cc/en/Reference/AnalogReference
    // analogReference(EXTERNAL);
    
    MIDI.begin();

    // a wannabe..
    MIDI.sendNoteOn(n, 127, MIDI_CH);  
    MIDI.sendNoteOn(n + 7, 127, MIDI_CH);  
    MIDI.sendNoteOn(n + 12, 127, MIDI_CH);  
    MIDI.sendNoteOn(n + 16, 127, MIDI_CH);
    MIDI.sendNoteOn(n + 19, 127, MIDI_CH);
    MIDI.sendNoteOn(n + 24, 127, MIDI_CH);
    delay(2500);            
    MIDI.sendNoteOff(n, 0, MIDI_CH);
    MIDI.sendNoteOff(n + 7, 0, MIDI_CH);
    MIDI.sendNoteOff(n + 12, 0, MIDI_CH);  
    MIDI.sendNoteOff(n + 16, 0, MIDI_CH);  
    MIDI.sendNoteOff(n + 19, 0, MIDI_CH);  
    MIDI.sendNoteOff(n + 24, 0, MIDI_CH);  
}

void loop()
{
    int value;
    int i;
    long sum;
    int average;
    int delta;
 
    sum=0;
    // this array works as FIFO
    // shift all values one position to the left, making room for the new reading,
    // in the meanwhile it sums for the average
    for (i=0; i < OVERSAMPLE-1; i++) {
        values[i]=values[i+1];
        sum+=values[i];
    }
    values[OVERSAMPLE-1]=analogRead(0);
    sum+=values[OVERSAMPLE-1];
    average=sum / OVERSAMPLE;

    // compute a trend compared to the previous
    delta=average - last_average;

    // save the current for the next iteration
    last_average=average;

    // try to limit flooding the midi channel
    if (abs(delta) > 0) {
        // note: you have to scale to 16384 because pitch bend messages
        // have 14 bits of data instead of 7 like most midi messages
        value=map(average, 0, MAX_SENSOR_VALUE, 0, 16384);
        midi_pitch_bend(value, MIDI_CH);
        // too much messages worsen things,
        // it depends also on the midi implementation on the synth
        delay(1);
    }
}
Pages: [1]