— ENSCI – FabLab/FabFlex

Radio 3.0 – la radio qui tweet. Christopher Santerre

 

Radio 3.0

 

Le Fablab de l’ensci, un terrain d’expérimentation

Radio 3.0 est un objet qui permet de sélectionner, d’écouter et de partager des données liées à des flux musicaux numériques. Mélangeant usages d’hier et pratiques d’aujourd’hui il est un support de recherche sur de nouvelles interactions possibles entre les hommes, les objets et le réseau. Revendiquant une conception libre, reproductible et reprogrammable aisément, RADIO 3.0 est un patchwork fait d’éléments de la grande industrie et de pièces sur mesures. Ayant largement recours à des technologies opensource comme Arduino,RADIO 3.0 fut une opportunité d’aborder l’ensemble des dimensions d’un projet de design de l’intention de départ au prototype fonctionnel. Ce fut l’occasion de tester directement l’interface de l’objet à travers ses différents capteurs et leur programmation.

ainsi qu’un puissant outil de production

Le Fablab de l’ENSCI m’a permis d’expérimenter la conception d’un objet complexe intégrant à la fois des savoirs-faires traditionnels comme celui du bois à de l’électronique de pointe. Cela a été l’occasion de générer de nombreux ponts entre les différents ateliers de l’école que j’ai pu utiliser pendant ces quelques mois comme un outil de prototypage et de production poussé.

 

Plans:

 

Liste des éléments composant la radio:

1x afficheur Sure Electronics matrice led rouge 32×8

1x airport express apple

1x ampli mono velleman 7w

1x hauts parleurs VISATON FRWS5 2watts

1x Arduino Uno

1x Arduino Ethernet Shield

1x Potentiomètre linéaire simple

1x Rotary encoder

1x Inverseur électronique

 

code arduino (provisoire)

#include <avr/pgmspace.h>

enum PinAssignments {  encoderPinA = 2,  encoderPinB = 3,};
// chris config#define CS1 13 #define CLK 10 // WR clock#define RD 5 #define DAT 7///*// uros config #define CS1 13  #define CLK 4 // WR clock #define RD 5  #define DAT 7*/#define RC_MASTER_MODE 0b100000110000#define SYS_DIS 0b100000000000#define SYS_EN 0b100000000010#define LED_OFF 0b100000000100#define LED_ON 0b100000000110#define N_MOS_COM8 0b100001000000#define PWM_16 0b100101011110#define PWM_1 0b100101000000#define CS_ON digitalWrite(CS1, LOW)#define CS_OFF digitalWrite(CS1, HIGH)#define CLK_ON digitalWrite(CLK, HIGH)#define CLK_OFF digitalWrite(CLK, LOW)#define DAT_ON digitalWrite(DAT, HIGH)#define DAT_OFF digitalWrite(DAT, LOW)
#define WORLD 0#define LOCAL 1
#define RESISTOR 0
#define TWEET 9
#define SWITCH 8

#define W_MATRIX 32#define H_MATRIX 8

byte image[32];byte p_image[32];boolean refreshImg = true;
boolean etat = false;int count = 0;
///encodeur
volatile unsigned int encoderPos = 0;unsigned int lastReportedPos = 1;
boolean A_set = false;boolean B_set = false;
long timerEnc = 0;int encoder = 0;
///end encodeur

boolean uglySwitch = false; // bug correction, change this auful thing
byte ser = 0;
long timer = 0;
boolean lock = false;
char* phrases[] = {

« Eclectik – Pierric Bailly », « La Tete au Carre – Les comites d’ethique », « PLACE DE LA TOILE 01.05.2011 », « Rencontre des Ateliers – Gilles Rougon », « Le Mouv – Le Post Politik 13.06.2011 », //  « CHIC – Le Freak », « Frederic Chopin – Minute Waltz », « Herbie Hancock – Cantaloupe Island »}; /// world 5-7

int local = 5;int world = 0;

String incoming = «  »;

const byte ascii[][6] PROGMEM = { // put this into the flash memory  0x00, 0x00, 0x00, 0x00, 0x00, 0x00,      // 32 (space)
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,      // 33 !
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,      // 34  »
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,      // 35 #
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,      // 36 0x
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,      // 37 %
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,      // 38 &
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,      // 39 ‘
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,      // 40 (
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,      // 41 )
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,      // 42 *
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,      // 43 +
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,      // 44 ,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,      // 45 –
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,      // 46 .
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,      // 47 /
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,      // 48 0
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,      // 49 1
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,      // 50 2
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,      // 51 3
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,      // 52 4
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,      // 53 5
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,      // 54 6
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,      // 55 7
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,      // 56 8
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,      // 57 9
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,      // 58 :
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,      // 59 ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,      // 60 <
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,      // 61 =
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,      // 62 >
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,      // 63 ?
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,      // 64 @
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,      // 65 A
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,      // 66 B
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,      // 67 C
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,      // 68 D
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,      // 69 E
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,      // 70 F
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,      // 71 G
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,      // 72 H
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,      // 73 I
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,      // 74 J
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,      // 75 K
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,      // 76 L
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,      // 77 M
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,      // 78 N
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,      // 79 O
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,      // 80 P
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,      // 81 Q
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,      // 82 R
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,      // 83 S
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,      // 84 T
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,      // 85 U
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,      // 86 V
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,      // 87 W
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,      // 88 X
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,      // 89 Y
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,      // 90 Z
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,      // 91
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,      // 92
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,      // 93
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,      // 94
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,      // 95
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,      // 96
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,      // 97 a
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,      // 98 b
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,      // 99 c
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,      // 100 d
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,      // 101 e
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,      // 102 f
0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,      // 103 g
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,      // 104 h
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,      // 105 i
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,      // 106 j
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,      // 107 k
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,      // 108 l
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,      // 109 m
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,      // 110 n
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,      // 111 o
0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,      // 112 p
0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,      // 113 q
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,      // 114 r
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,      // 115 s
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,      // 116 t
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,      // 117 u
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,      // 118 v
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,      // 119 w
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,      // 120 x
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,      // 121 y
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,      // 122 z
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,      // 123
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,      // 124
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,      // 125
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,      // 126
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00 };    // 127
void setup() {
pinMode(CS1, OUTPUT);  pinMode(CLK, OUTPUT);  pinMode(RD, OUTPUT);  pinMode(DAT, OUTPUT);
commandWrite(SYS_EN);  commandWrite(LED_ON);  commandWrite(RC_MASTER_MODE);  commandWrite(N_MOS_COM8);  commandWrite(PWM_16);
initImage();  for (int i=0; i<32; i++) p_image[i] = 0;

///  Serial.begin(9600);

/// SWITCH  pinMode(SWITCH, INPUT);  digitalWrite(SWITCH, HIGH); // pull down
pinMode(TWEET, INPUT);
timer = millis();
//for (int i=0; i<5; i++) Serial.println(getLength(phrases[i]));

if (getWorldLocalSwitch() == WORLD) {    Serial.println(world);  }   else {    Serial.println(local);  }
///encodeur  pinMode(encoderPinA, INPUT);   pinMode(encoderPinB, INPUT);
digitalWrite(encoderPinA, HIGH);  // turn on pullup resistor  digitalWrite(encoderPinB, HIGH);  // turn on pullup resistor

// encoder pin on interrupt 0 (pin 2)  attachInterrupt(0, doEncoderA, CHANGE);  // encoder pin on interrupt 1 (pin 3)  attachInterrupt(1, doEncoderB, CHANGE);

////

}

void loop() { // this is main loop for drawing
events();
/*  Serial.print(world);   Serial.print( » « );   Serial.println(local);   */

if (millis()>timer + 70){    ////    makeScene();    draw();    ////    timer = millis();  }

}

void makeScene() {  background(0);  // phrase scrolling  count–;
if (getWorldLocalSwitch() == WORLD) {    // Serial.println(getLength(phrases[world]));
if (count==-(getLength(phrases[world])*6))       count = W_MATRIX;
drawPhrase(phrases[world],count,0);
}   else {
if (count==-(getLength(phrases[local])*6))       count = W_MATRIX;
drawPhrase(phrases[local],count,0);  }

}

void draw() { // don’t touch here
CS_ON;  addressWrite(0x00);  for (int i=0; i<32; i++) {    byteOut(image[i]);  }  CS_OFF;
}
int getLength(String s) {  return s.length();}

void events() {
///SWITCH  static int lastWorldChange = 0;  int wlc = getWorldLocalSwitch();  if (lastWorldChange != wlc) {    worldLocalChange();    uglySwitch = false;  }
lastWorldChange = wlc;  ///END SWITCH
//// encodeur
if (lastReportedPos != encoderPos) {
/*    Serial.print(« Index: »);     Serial.print(encoderPos, DEC);     Serial.println();          */
if (millis() > timerEnc+600) {
if (lastReportedPos>encoderPos) {        encoder = 1;         listChange();      }      else {        encoder = 2;        listChange();      }
}
timerEnc = millis();
lastReportedPos = encoderPos;  }  /// end encodeur

///TWITTER   static int lastTweet = 0;  int tt = getTweet();  if (lastTweet != tt) tweet();  lastTweet = tt;  ///END TWITTER
}
void tweet() {  background(0);  drawPhrase(« share », 0,0);  Serial.println(8);  draw();  delay(1500);  count = W_MATRIX;}

void worldLocalChange() {
background(0);
if (getWorldLocalSwitch() == WORLD) {
drawPhrase(« local », 0,0);    draw();    Serial.println(9); // 8- stop    delay(1500);    count = W_MATRIX;    Serial.println(world);
}   else { //// WORLD
drawPhrase(« world », 0,0);    draw();    Serial.println(9); // 8- stop    delay(1500);    count = W_MATRIX;    Serial.println(local);  }

}
void listChange() {
switch(encoder) {  case 1: /// turn UP
if (getWorldLocalSwitch() == WORLD) {
if (world<4)        world++;       else world = 0;      uglySwitch = true;      scrollUpPhrase(phrases[world]);      Serial.println(world);
}     else {
if (uglySwitch == false) {        if (local<7)          local++;         else local = 5;      }      scrollUpPhrase(phrases[local]);      Serial.println(local);    }    break;

case 2: /// turn DOWN
if (getWorldLocalSwitch() == WORLD) {

if (world>0)        world–;       else world = 4;      scrollDownPhrase(phrases[world]);      Serial.println(world);    }     else {
if (local>5)        local–;       else local = 7;      scrollDownPhrase(phrases[local]);      Serial.println(local);    }
break;  }
delay(1500);  count = 0;
/*  Serial.print(world);   Serial.print( » « );   Serial.println(local);   */

}

int getWorldLocalSwitch() {  return digitalRead(SWITCH); }

int getTweet() {  return digitalRead(TWEET);}

void invert() {  for (int i=0; i<32; i++) {    image[i] = image[i] ^ 255;  }}
/*void drawImage(byte *img, int x, int y, int w, int h) {  if ( ((y+h)>0) && (y<H_MATRIX) ) { // define y on screen if ( ((x+w)>0) && (x<W_MATRIX) ) { // define x on screen  byte imgA[W_MATRIX]; for (int i=0; i<W_MATRIX; i++) imgA[i] = 0; //x for (int i=0; i<w-x; i++)  imgA[x+i] = img[i];   //y for (int i=0; i<W_MATRIX; i++) { imgA[i] = (y>0) ? imgA[i]<<y : imgA[i]>>y; image[i] = imgA[i]; } } }   } */
void scrollDownPhrase(char *p2) {
byte imgA[W_MATRIX];  for (int j=0; j<W_MATRIX; j++) imgA[j] = image[j];
for (int i=0;i<=H_MATRIX;i++) {
//y    for (int j=0; j<W_MATRIX; j++)       image[j] = imgA[j]<<i;

drawPhrase(p2, 0, H_MATRIX-i);    draw();    delay(100);  }}
void scrollUpPhrase(char *p2) {
byte imgA[W_MATRIX];  for (int j=0; j<W_MATRIX; j++) imgA[j] = image[j];
for (int i=0;i<=H_MATRIX;i++) {
//y    for (int j=0; j<W_MATRIX; j++)       image[j] = imgA[j]>>i;

drawPhrase(p2, 0, i-8);    draw();    delay(100);  }}
void drawPhrase(String phrase, int x, int y) {
int pos = x;  for (int i=0; i<phrase.length(); i++) {    if (pos<W_MATRIX) {      drawLetterAt(phrase.charAt(i), pos, y);    }     else {      break;    }    pos+=6;  }
}
void drawLetterAt(char letter, int x, int y) {
if ((x<W_MATRIX) && (x>-6)) {
if ((letter>=32) && (letter<=127)) letter-=32;
byte ll[6];    ll[0] = pgm_read_byte(&(ascii[letter][0]));     ll[1] = pgm_read_byte(&(ascii[letter][1]));     ll[2] = pgm_read_byte(&(ascii[letter][2]));     ll[3] = pgm_read_byte(&(ascii[letter][3]));     ll[4] = pgm_read_byte(&(ascii[letter][4]));     ll[5] = pgm_read_byte(&(ascii[letter][5]));     byte *let = &ll[0];
if (x<0) { // left offscreen
////drawing on the beginning of the screen      let+=abs(x); // put on the new first position      for (int i=0; i<x+6; i++) { // only draw in visible area from 0 till something (x+6)        if ((i+6)<W_MATRIX)  {/// don’t draw in offscreen, break out
byte buff = *let++;          if (y<0) {            buff = buff << abs(y);          }           else {            buff = buff >> y;
}
image[x+i] = image[x+i] | buff;
}        else break;      }

}     else {      /// drawing anywhere on the screen      for (int i=0; i<6; i++) {         if ((i+6)<W_MATRIX)  {/// don’t draw in offscreen break out
byte buff = *let++;          if (y<0) {            buff = buff << abs(y);
}           else {            buff = buff >> abs(y);
}
image[x+i] = image[x+i] | buff;
}        else break;      }
}  }

}
void background(int a) { // enter 1 or 0  for (int i=0; i<32; i++) {    image[i] = (a>0) ? 255 : 0;  }}
void initImage() { /// first image in the array// blank array  for (int i=0; i<32; i++) {    image[i] = 0;  }}/* this function don’t use PROGMEM flash memory char *getLetter(char l) { return ascii[l-32]; } */

// Interrupt on A changing statevoid doEncoderA(){  // Test transition  A_set = digitalRead(encoderPinA) == HIGH;  // and adjust counter + if A leads B  encoderPos += (A_set != B_set) ? +1 : -1;}
// Interrupt on B changing statevoid doEncoderB(){  // Test transition  B_set = digitalRead(encoderPinB) == HIGH;  // and adjust counter + if B follows A  encoderPos += (A_set == B_set) ? +1 : -1;}

void byteOut(byte a) {  shiftOut(DAT,CLK,LSBFIRST,a);}

void commandWrite(unsigned int command) {
unsigned char i;  unsigned int j;  command = command & 0x0fff; //12-bit command word, upper four bits masked  CS_OFF;  CS_ON;
for (i=0; i<12; i++) {    CLK_OFF;
j = command & 0x0800; // return MSB    command = command << 1; //Move the control character to the left one    j = j >> 11;    digitalWrite(DAT, j);    CLK_ON;  }
CS_OFF;
}
void addressWrite(unsigned char address) {  unsigned char i,temp;   address = address & 0x7f;   CLK_OFF;  DAT_ON;  CLK_ON;   CLK_OFF;   DAT_OFF;  CLK_ON;   CLK_OFF;   DAT_ON;  CLK_ON;   for(int i=0; i<7; i++) {    CLK_OFF;     temp = address & 0x40;     address = address << 1;     temp = temp >> 6;     digitalWrite(DAT,temp);     CLK_ON;   }  CLK_OFF;}

1 comment
  1. […] Radio 3.0 – la radio qui tweet. ENSCI – FabLab […]

Submit comment

*