Youtube Channel
scrivimi: fraranux@gmail.com
chiamami: 345 04.22.\pi

venerdì 28 novembre 2014

Charlie Plexing, Chubby Bunny, addobbi natalizi con l'attiny 85 e altre sventure.

intanto carico il filmatino di un aggeggio che stamane ho appeso alla porta del mio laboratorio,
un bel lavoretto realizzato grazie alla sapiente programmazione di Dario Gavezzone . (La rima imponeva).



Tutta l'elettronica è basata su di un ATtiny 85, qualcosa in merito lo trovate anche QUI!

Lo schema a fritzing è un disastro:








più comprensibile lo schema dei soli led recuperato direttamente dalla pagina di wikipedia qui sotto:




lo sketch è questo:

#include <avr/pgmspace.h>  //This is in the Arduino library

// inizio implementazione assert con output in compilazione
#define CONCAT_TOKENS( TokenA, TokenB )       TokenA ## TokenB
#define EXPAND_THEN_CONCAT( TokenA, TokenB )  CONCAT_TOKENS( TokenA, TokenB )
#define ASSERT( Expression )                  enum{ EXPAND_THEN_CONCAT( ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
#define ASSERTM( Expression, Message )        enum{ EXPAND_THEN_CONCAT( Message ## _ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
// fine implementazione assert con output in compilazione

#define ISDIGIT(n) (n >= '0' && n <= '9')

#define OCTAVE_OFFSET 0
#define SPEAKER_PIN 4
#define BUTTON_PIN 3

const int notes[] = { 0,
 262,  277,  294,  311,  330,  349,  370,  392,  415,  440,  466,  494, // 4
 523,  554,  587,  622,  659,  698,  740,  784,  831,  880,  932,  988, // 5
1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976, // 6
2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951, // 7
};

char *songs[] = {
  "R:d=4,o=5,b=160:8g,a,8g,e,c6,a,2g.,8g.,16a,8g.,16a,g,c6,1b,8f,g,8f,d,b,a,2g.,8g.,16a,8g.,16a,g,d6,2c.6",
  "J:d=4,o=5,b=112:8a,8a,a,8a,8a,a,8a,8c6,8f.,16g,2a,8a#,8a#,8a#.,16a#,8a#,8a,8a.,16a,8a,8g,8g,8a,g,c6",
  "W:d=8,o=5,b=140:4d,4g,g,a,g,f#,4e,4c,4e,4a,a,b,a,g,4f#,4d,4f#,4b,b,c6,b,a,4g,4e,4d,4e,4a,4f#,2g",
};
const char pins[] = {0, 1, 2};
const char ledPins[5][2] = {
  {0, 1},
  {1, 0},
  {1, 2},
  {2, 1},
  {2, 0},
};
byte giro = 0;
byte j = 0;
#define NUM_OF_SONGS 3
#define NUM_OF_PINS (sizeof(pins) / sizeof(char))
#define NUM_OF_LEDS 5
ASSERT(NUM_OF_LEDS <= (NUM_OF_PINS * (NUM_OF_PINS-1)));
void setup(void) {
  pinMode(SPEAKER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop(void) {
  alloff();
  if ( digitalRead(BUTTON_PIN) == LOW ) {
    play_rtttl(songs[giro]);
    giro = (giro < (NUM_OF_SONGS -1)) ? giro + 1 : 0;
  }
}
void play_rtttl(char *p) { // http://www.interactiondesign.se/wiki/attiny
  // Absolutely no error checking in here
  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;
  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)
  // legge il titolo
  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'
  // get default duration
  if(*p == 'd') {
    p++; p++;              // skip "d="
    num = 0;
    while(ISDIGIT(*p)) {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }
  // get default octave
  if(*p == 'o') {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }
  // get BPM
  if(*p == 'b') {
    p++; p++;              // skip "b="
    num = 0;
    while(ISDIGIT(*p)) {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }
  // quante note da un quarto stanno in un minuto
  wholenote = (60 * 1000L / bpm) * 4  ;  // this is the time for whole note (in milliseconds)
  // now begin note loop
  while(*p) {
    // first, get note duration, if available
    num = 0;
    while(ISDIGIT(*p)) {
      num = (num * 10) + (*p++ - '0');
    }

    if (num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after
    // now get the note
    note = 0;
    switch(*p) {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;
    // now, get optional '#' sharp
    if(*p == '#') {
      note++;
      p++;
    }
    // now, get optional '.' dotted note
    if(*p == '.') {
      duration += duration/2;
      p++;
    }
    // now, get scale
    if(ISDIGIT(*p)) {
      scale = *p - '0';
      p++;
    } else {
      scale = default_oct;
    }
    scale += OCTAVE_OFFSET;
    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)
    // now play the note
    if(note) {
      freqout(notes[(scale - 4) * 12 + note], duration);
    } else {
      delay(duration);
    }
  }
}
void freqout(int freq, int t) {
  freqout(freq, t, SPEAKER_PIN);
}
void freqout(int freq, int t, byte speaker) { // http://www.arduino.cc/playground/Main/Freqout
  turnon(random(0, NUM_OF_LEDS - 1));
  // freq in hz, t in ms
  const int hperiod = 500000 / freq - 7;              // subtract 7 us to make up for digitalWrite overhead
  const long cycles = ((long)freq * (long)t) / 1000;  // calculate cycles

  pinMode(SPEAKER_PIN, OUTPUT);                       // turn on output pin
  for (long i = 0; i <= cycles; i++) {                // play note for t ms  - SOFTWARE PWM?
    digitalWrite(SPEAKER_PIN, HIGH);
    delayMicroseconds(hperiod);
    digitalWrite(SPEAKER_PIN, LOW);
    delayMicroseconds(hperiod - 1);                   // - 1 to make up for digitaWrite overhead
  }
  pinMode(SPEAKER_PIN, INPUT);                        // shut off pin to avoid noise from other operations
//  alloff();
//  j = (j < (NUM_OF_LEDS - 1)) ? j + 1 : 0;
}

void turnon(int led) { // http://www.instructables.com/id/CharliePlexed-LED-string-for-the-Arduino/
  // This turns on a certian led from the list of leds
  int pospin = ledPins[led][0];
  int negpin = ledPins[led][1];
  pinMode (pospin, OUTPUT);
  digitalWrite (pospin, HIGH);
  pinMode (negpin, OUTPUT);
  digitalWrite (negpin, LOW);
}

void alloff() { // http://www.instructables.com/id/CharliePlexed-LED-string-for-the-Arduino/
  // This turns all the LED's off
  for(int i = 0; i < NUM_OF_PINS; i++)
    pinMode (pins[i], INPUT);
}



Nessun commento:

Posta un commento