— ENSCI – FabLab/FabFlex

Archive
Radio2.0

 

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;}

Read More

SMS slingshot

Projet très intéressant d’interaction physique sur du contenu numérique.

Read More

test test

Premier test d’affichage sur l’afficheur via arduino.

Cet afficheur à la particularité d’être pré-monté et d’intégrer un puce facilitant sa programmation

en centralisant l’ensemble des commandes.

Néanmoins il à été nécessaire de ré-interpréter entièrement le code fournit pour qu’il soit compréhensible par arduino.

Malgré cette étape un peu délicate, ce composant facilite grandement le montage (seulement 5 fils sont nécessaire pour le relier à Arduino) et la manutention de l’ensemble.

Il est possible d’afficher des images BITMAP un fois transformées en code via un petit logiciel processing.

>>> La prochaine étape sera de gérer des animations verticales et horizontales de textes afin de pouvoir naviguer dans les menu de la radio.

Fabricant de l’afficheur:

http://www.sureelectronics.net/goods.php?id=1119

Read More

Essai de tweet via arduino+airport

Essai de tweet avec arduino émis par wifi via un airport express.

 

Read More

control airTunes depuis applescript

Read More

Read More

Olinda est une radio évolutive conçue par les designers de berglondon.

Modulable grace à une logique d’assemblage par module qui permet d’ajouter des fonctions à la radio.

Intelligente aussi dans le sens ou elle apprend de son usager en lui proposant une sélection des fréquences les plus écoutées. (l’un des designer fait référence à l’écriture prédictive de Google qui devance les volontés de l’usager).

L’idée forte de ce projet était d’intégrer des logiques propres a la base au Web 2.0 (ouverture, participation et modification apportées par les usagers) dans la conception d’un objet réel.

Cette radio à été développé en partenariat avec le centre de R&D Audio et Music Interactive de la BBC.

+ d’infos ici

 

Read More

Produite pendant une dizaine d’années, entre 1971 et 1981. La Beolit 600 est une radio de la marque danoise Bang & Olufsen. Superbement conçue en aluminium et plastique de couleur (noire en l’occurence) elle à l’avait la particularité de contenir une petite enveloppe faisant état de l’assemblage de ses composants. Facilitant ainsi sa réparation en cas de besoin.

via Berglondon.com

Read More

Victor Papanek (Design for the Real World) à conçu ce récepteur radio en 1962.

Destinée à la base au pays du tiers monde elle est constituée d’une canette de jus de fruit

vide en guise de coque de protection et fonctionne avec de la parafine pour l’énergie.

Son coût de fabrication était alors de 9cents.

Read More

Voici une radio faite dans le cadre d’un diplôme de l’université Suédoise d’Umea.
Le principe est simple, des petits disques rfid permettent lire ses listes de lectures spotify.

Merci à Thélo pour le lien.

http://www.trendsnow.net/2011/02/spotify-player-concept.html

Read More