Skip to content

Storytelling stickers update

Wrapping up what’s happened to the storytelling stickers!

THE READER

The RFID reader is working! It took a while though. I did some search and ended up taking arduino codes from http://blog.formatlos.de/2008/12/08/arduino-id-12/ featuring the AF_SoftSerial library. It’s very well written and comprehensive. The scripts added a kicking off step and a disconnection detection as well. Great work! A simple processing sketch was made to display the identifier code.

The tag needs to be really close to the reader to be recognized, which is fine in my project. But since I probably needs to get reading from both ends of a miniature trumpet/horn, that might not be good enough. I’m trying to build some antenna for the reader and see if it could extend the accessibility.

THE TAG

The tags arrived too. I ordered 300 raw EM4001 RFID tags (meaning that they come with exposed coil antennae) and unfortunately a lot of them broke. A lot of soldering is ahead! But I got enough to start anyway, like a hundred.

image019 image017 image0251

THE SOUND

I got the wave sound shield from Adafruit and finished assembling while procrastinating. But I haven’t tried to use them because it doesn’t record to the card and I decided to fall back to use a computer in this phrase.

So now it works like this. Whenever a card/tag/sticker is seen/read, according to the mode an audio clip associated to the tag ID would be recorded or played, by the computer. All sound files are stored on the computer instead of any hardware/memory card as I previously planned. The processing sketch was adapted to keep track of a known card and pick the corresponding sound file to play/record.

[Videos to be uploaded soon]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
import ddf.minim.signals.*;
import ddf.minim.*;
import ddf.minim.analysis.*;
import ddf.minim.effects.*;
import processing.serial.*;

Serial myPort;
boolean connected = false;

String activeTag = "Waiting...";
PFont f = createFont("Helvetica", 50);

Hashtable cards;
Minim minim;
AudioInput in;
AudioRecorder recorder;
AudioPlayer player;

String previousCard = "";
boolean playMode = false;
boolean autoPilot = true;

void setup()
{
    println("connecting...");
    myPort = new Serial(this, Serial.list()[0], 9600);
    myPort.clear();
    cards = new Hashtable();

    loadCards();

    minim = new Minim(this);
    in = minim.getLineIn(Minim.STEREO, 2048);

    size(800,600);
    background(0);
    fill(255);
    noStroke();
    textAlign(CENTER);
    textFont(f);
    text("WAITING",width / 2, height / 2);
}

void draw()
{
    background(0);
    if (!connected)
    {
        myPort.write('C');
    }
    else
    {
        text(activeTag,width / 2, height / 2);

        if (playMode)
        {
            text("PLAYING",width / 2, height / 2 + 90);
        }
        else
        {
            text("RECORDING",width / 2, height / 2 + 90);
        }
        if (recorder != null)
        {
            stroke(255);
            if (playMode)
            {
                if (player != null)
                {
                    for(int i = 0; i < player.left.size()-1; i++)
                    {
                        line(i, 50 + player.left.get(i)*50, i+1, 50 + player.left.get(i+1)*50);
                        line(i, 150 + player.right.get(i)*50, i+1, 150 + player.right.get(i+1)*50);
                    }
                }
            }
            else
            {
                for(int i = 0; i < in.bufferSize() - 1; i++)
                {
                    line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
                    line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
                }
            }  
        }
    }
}

void closePlayer()
{
    if (player != null && player.isPlaying())
    {
        try
        {
            player.close();
        }
        catch (Exception e)
        {

        }
    }
}

void closeRecorder()
{
    if (recorder != null/* && recorder.isRecording()*/)
    {
        try
        {
            recorder.endRecord();
            recorder.save();
        }
        catch(Exception e)
        {

        }
    }
}

void loadCards()
{
    cards.clear();
    String []lines = loadStrings("index.txt");
    if (lines == null)
    {
        return;
    }

    for (int i = 0; i < lines.length ; i++)
    {
        String card = trim(lines[i]);
        cards.put(card, true);
    }
}

void dumpCards()
{
    PrintWriter writer = createWriter("data/index.txt");

    for (Enumeration e = cards.keys() ; e.hasMoreElements() ;)
    {
        String card = e.nextElement().toString();
        writer.println(card);
    }

    writer.flush();
    writer.close();
}

void serialEvent(Serial port) {
    String myString = port.readStringUntil(' ');
    if (myString != null)
    {
        myString = trim(myString);
        if (myString.equals("connected"))
        {
            connected = true;
            println("connected~!");
        }
        else
        {
            if (myString.equals("0000000000"))
            {
                activeTag = "Disconnected";

                if (playMode && player != null)
                {
                    println(previousCard + ": Disconnect from playing");
                    closePlayer();
                }
                else
                {
                    println(previousCard + ": Disconnect from recording");
                    closeRecorder();
                }
                previousCard = "";

            }
            else
            {
                activeTag = myString;

                if (!cards.containsKey(activeTag))
                {
                    cards.put(activeTag,true);
                    dumpCards();
                    if (autoPilot)
                    {
                        closePlayer();
                        playMode = false; //auto switch to record      
                        println("Autopilot: switch to record mode");           
                    }
                }
                else //found
                {
                    if (autoPilot)
                    {
                        playMode = true; //auto switch to play 
                        closeRecorder();
                        println("Autopilot: switch to play mode");                     
                    }
                }

                if (playMode)
                {
                    if (cards.containsKey(activeTag))
                    {
                        println(activeTag + ": Start playing new file, disconnect from previous " + previousCard);

                        closePlayer();

                        println("loading " + activeTag + " to play");
                        player = minim.loadFile("data/" + activeTag + ".wav", 2048);
                        player.play();
                        player.loop();
                    }
                    else
                    {
                        println(activeTag + ": Not recorded yet");
                    }
                }
                else //record mode
                {
                    if (activeTag != previousCard)
                    {
                        println(activeTag + ": Start playing new file, disconnect from previous " + previousCard);
                        closePlayer();                     
                        closeRecorder();
                    }

                    recorder = minim.createRecorder(in, "data/" + activeTag + ".wav", true);
                    recorder.beginRecord();
                }

                previousCard = activeTag;
            }
        }
    }
}

void stop()
{
        in.close();

    closePlayer();
    closeRecorder();

    minim.stop();
    super.stop();
}

void keyPressed()
{
    if (key == ' ')
    {
        playMode = !playMode;

        if (playMode)
        {
            println("play mode");
        }
        else
        {
            println("record mode");
        }
    }

    if (key == 'a')
    {
        autoPilot = !autoPilot;

        if (autoPilot)
        {
            println("Autopilot: ON");
        }
        else
        {
            println("Autopilot: OFF");
        }
    }
}

THE NAME

Any thoughts on a name for the toy?

One Comment

  1. nice project … cheers martin

    Posted on 10-Apr-09 at 4:30 am | Permalink

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*