Psychique diseuse de bonne aventure - un automate qui lit l’esprit de Twitter (26 / 32 étapes)

Croquis complet avec quelques interprétations

Version 9. C’est l’esquisse de traitement psychique de cerveau au moment de la libération de ce Instructable.
Toute modification sera sur le repo Git
https://github.com/rosemarybeetle/Psychic-Fortune-Teller

crédits

// -----------------------
// ----
// PSYCHIC FORTUNE TELLER
// 2013
// http://makingweirdstuff.blogspot.com
// version 9
/* -----------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see .
----------------------
*/

//
// This sketch is the mind control of Psychic Fortune Teller, an automaton that can read the collective mind of twitter
// It has a Processing brain connected to a Twitter app, connecting via OAUTH
// It harvests tweets from predefined searchs
// Deconstructs the weet content into words, hashtags, usernames and urls
// Then uses these to create fortune readings, which it speaks using text-to-speeach
// it also tweets a summary.

//
// RESPECT to...
//
// JER THORP - Visualisation is based on his code example
// see http://blog.blprnt.com/blog/blprnt/updated-quick-tutorial-processing-twitter
// Awesome!
//
// The people behind twitter4j
// see https://github.com/yusuke/twitter4j/network
// using here, version 3.03
// NOTE - you have to have the twitter4j library installed in the libraries folder for this to work!
// You need to register your app to get OAUTH keys for Twitter4j
// You can put them in a separate tab in your sketch
//
// Andreas Schlegel - controlP5 GUI Library
// see http://www.sojamo.de/libraries/controlP5/
// For positioning see (also Andreas Schlegel -
// https://code.google.com/p/controlp5/source/browse/trunk/examples/controlP5button/controlP5button.pde?r=6
// ----
// Nikolaus Gradwohl for the GURU text to speech library for Processing
// see http://www.local-guru.net/blog/pages/ttslib
// -----------------------

// -----

entrée en vigueur

// >>>>>>
boolean serialCheckInt=true;
boolean grabtweetCheckInt=true;
boolean loadSettingsFirstLoadFlag=true;
boolean loadstopWordsCheckInt=true;
// <<<<<< end load flags

// >>>>> fortune variables initialisations
int tweetTextOutro = int (random(99));
String tweetSendTrigger ="fireTweet";
String fortuneGreeting = "I have stared deep into the hive mind. ";
String fortune = "";
String fortuneSpoken = "";
int widthRandomiser = 120;
// <<<<<<

// >>>>>> gui variables init...
String tfUserCurrent =""; // used to check what is in the username text box
String tfTextCurrent =""; // used to check what is in the free-text text box
int valFocus = 0; // default
color focusBackgroundColor = color (255, 255, 00);
color focusOffBackgroundColor = color (0, 0, 0);
color focusOffColor = focusBackgroundColor ;
color focusColor = focusOffBackgroundColor;
color clPanel = color(70, 130, 180);
// <<<<<<

// >>>>>> ArrayLists to hold all of the words that we get from the imported tweets
ArrayListstopWords = new ArrayList();
ArrayListcleanTweets = new ArrayList();
ArrayListwords = new ArrayList();
ArrayListhashtags = new ArrayList();
ArrayListusernames = new ArrayList();
ArrayListurls = new ArrayList();
ArrayList tweetster = new ArrayList();
String uberWords [] = new String[0]; //massive array to build up history of words harvested
String uberHashtags [] = new String[0]; //massive array to build up history of hashtags harvested
String uberUsers [] = new String[0]; //massive array to build up history of users harvested
String uberUrls [] = new String[0]; //massive array to build up history of urls harvested
String queryString = ""; //
String queryType = ""; //
ArrayListfortFrags1 = new ArrayList();
ArrayListfortFrags2 = new ArrayList();
ArrayListfortFrags3 = new ArrayList();
ArrayListfortFrags4 = new ArrayList();

// <<<<<< Variables for admin and tweettexts - e.g Array for containing imported admin settings from Google spreadsheet (init with default settings)
String adminSettings [] = {
"#hivemind", " "weird", "100", "50000", "h", "500", "Psychic Hive-Mind Fortune Reader", "Greetings Master. I am a-woken"
};

String tweetTextIntro="";
String readingSettingText="";
int panelHeight = 60;
int border = 40;
int boxY = 515;
int boxWidth = 270;
int boxHeight = 40;
int columnPos2_X = 310;

// >>>>>> grabTweets Timer settings >>>>>>>>>>>
float grabTime = millis();
float timeNow = millis();
String stamp = year()+"-"+month()+"-"+day()+"-"+hour()+"-"+minute();// <<<<<<

Mettre en place la bibliothèque de renforcement interface GUI (ControlP5)

// >>>>>> GUI library and settings
import controlP5.*; // import the GUI library
ControlP5 cp5; // creates a controller (I think!)
ControlFont font;
controlP5.Button b;
controlP5.Textfield tf;
controlP5.Textlabel lb;
// <<<<<<<

Mettre en place une bibliothèque de conversion texte-parole (le gourou)

// >>>>>>> import GURU text-to-speech library
import guru.ttslib.*; // NB this also needs to be loaded (available from http://www.local-guru.net/projects/lib/ttslib-0.3.zip)
TTS tts; // create an instance called 'tts'

// <<<<<<<

// >>>>>>> import standard processing Serial library
import processing.serial.*;

Serial port; // create an instance called 'port'
// <<<<<<<

// >>>>>> needed to stop Twitter overpolling from within sendTweet
float tweetTimer = 5000; // wait period (in milliseconds) after sending a tweet, before you can send the next one
float timerT=millis(); // temporary timer for sendTweet
float delayCheck; //delayCheck; // THIS IS IMPORTANT. it i what stops overpollin g of the Twitter API
// <<<<<< End of main initialisation

Fonction SETUP() principal...

void setup() {
tts = new TTS(); // create text to speech instance
tts.speak(adminSettings[8]);// preloaded, not web
println (" adminSettings 1 " + adminSettings); // DEBUG STUFF
for (int i = 0 ; i < adminSettings.length; i++) {
println("adminSettings["+i+"]= "+adminSettings[i]); // DEBUG STUFF
}
updateDisplayVariables();
try {
loadRemoteAdminSettings(); // loads Twitter search parameters from remote Google spreadsheet
println ("adminSettings 2 "+adminSettings);
tts.speak("I am connected to the web. Master.Your commands have been loaded into my brain"); // DEBUG STUFF - SPOKEN OUT. ONLY WORKS IF CONNECTION WORKS
}
catch (Exception e) {
tts.speak("I am sorry. I am not able to connect to the web. Your commands have not been loaded into my brain master"); // DEBUG STUFF
}
loadRemoteStopWords();// load list of stop words into an array, loaded from a remote spreadsheet

// >>>>>>> screen size and settings....
size(screen.width-border, screen.height-border);// USE THIS SETTING FOR EXPORTED APPLICATION IN FULLSCREEN (PRESENT) MODE
background(0); // SET BACKGROUND TO BLACK
// <<<<<<<

// >>>>> Make initial serial port connection handshake
println(Serial.list());// // DEBUG STUFF - display communication ports (use this in test for available ports)
try {
port = new Serial(this, Serial.list()[0], 115200); // OPEN PORT TO ARDUINO
}
catch (ArrayIndexOutOfBoundsException ae) {
// if errors
println ("-------------------------");
println ("STOP - No PORT CONNECTION");
println ("Exception = "+ae); // print it
println ("-------------------------");
println ("-------------------------");
}
// <<<<<<<
buildAdminPanel();

smooth();

grabTweets(); // Now call tweeting action functions...

println ("finished grabbing tweets");
println ();
println ();
} // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end of setup() <<<<<<<<<<<<<<<<<<<<<<<<<<

Fonction principale LOOP()

void draw() {
int panelTop= height-panelHeight;
buttonCheck("HELLO"); // on screen check button every loop

timeNow=millis();

try {
println ();
if ((timeNow-grabTime)>float(adminSettings[4])) {
grabTweets();
}

// >>>>>> Draw a faint black rectangle over what is currently on the stage so it fades over time.
fill(0, 30); // change the latter number to make the fade deeper (from 1 to 20 is good)
rect(0, 0, width, height-panelHeight);
// <<<<<<

// >>>>>>> WORDS
// Draw a word from the list of words that we've built
int i = (int (random (words.size())));
String word = words.get(i);
println ("word = "+word+" #"+i);
// <<<<<<<

// >>>>>>> HASHTAGS
//Draw a hashtag from the list of words that we've built
int j = (int (random (hashtags.size())));
String hashtag = hashtags.get(j);
// <<<<<<<

// >>>>>> USERNAMES
//Draw a username from the list of words that we've built
int k = (int (random (usernames.size())));
String username = usernames.get(k);
// <<<<<<

// >>>>>> URLS
//Draw a url from the list of words that we've built
int l = (int (random (urls.size())));
String url = urls.get(l);
// <<<<<<

//-------------
// >>>>> Put url somewhere random on the stage, with a random size and colour
fill(255, 255, 0, 255);
textSize(random(30, 40));
text(url, random(width)-widthRandomiser, random(panelTop)); //
// <<< SEND URL TO THE SCREEN

// >>> SENDs HASHTAG TO THE SCREEN WITH DIFFERENT SIZE
fill(255, 0, 0, 255);
textSize(random(40, 45));
text("#"+hashtag, random(width)-widthRandomiser, random (panelTop));
// <<< END SEND HASHTAG#

// >>>SEND WORD TO SCREEN ALSO WITH DIFFERENT SETTINGS
textSize(random(45, 60));
fill(255, 255);

text(word, random(width)-widthRandomiser, random (panelTop));
// <<< END SEND WORD

// >>> SEND USERNAME TO SCREEN
fill(0, 255, 22, 255);
textSize(random(35, 45));
text(" random(width)-widthRandomiser, random (panelTop));
// <<< END SEND USERNAME

// --------------
// following is for text boxes background.
tfUserCurrent=tf.getText() ; //check the text box content every loop
println ("tfUserCurrent= "+tfUserCurrent); // DEBUG STUFF
}
catch (Exception e) {
}
finally
{
println ("inside DRAW()");
}
checkSerial() ; // check serial port every loop
}

Fonction SENDTWEET() - envoie tweets !

// >>>>>>>>>>>>>>>>>>>>>>>> SEND THAT TWEET >>>>>>>>>>>>>>>

void sendTweet (String tweetText) {

if ((tfUserCurrent.equals(""))!=true) { // THE BOX CAN'T BE EMPTY
updateDisplayVariables();
//
timerT=millis(); // reset the timer each time

if (timerT-delayCheck>=tweetTimer)
// this is needed to prevent sending multiple times rapidly to Twitter
// which will be frowned upon!
{
delayCheck=millis(); // RESET A TIMER

println("tweet being sent"); // DEBUG STUFF
println("tfUserCurrent = "+ tfUserCurrent); // DEBUG STUFF
tweetTextIntro = readingSettingText; // INITIALISE THE INTRO TEXT VARIABLE...
readFortune(tweetText);
tts.speak(fortuneSpoken);
println("tweet Send actions complete over"); // DEBUG STUFF
println();

//
ConfigurationBuilder cb2 = new ConfigurationBuilder();
// ------- NB - the variables twitOAuthConsumerKey, are in a seperate tab
cb2.setOAuthConsumerKey(twitOAuthConsumerKey);
cb2.setOAuthConsumerSecret(twitOAuthConsumerSecret);
cb2.setOAuthAccessToken(twitOAuthAccessToken);
cb2.setOAuthAccessTokenSecret(twitOAuthAccessTokenSecret);

Twitter twitter2 = new TwitterFactory(cb2.build()).getInstance();

try {
Status status = twitter2.updateStatus(fortune);
println("Successfully tweeted the message: "+fortune + " to user: [ + status.getText() + "]."); // DEBUG STUFF
delayCheck=millis();
}
catch(TwitterException e) {
println("Send tweet: " + e + " Status code: " + e.getStatusCode());
} // end try
;
}
}
else {
tts.speak("You have not entered your Twitter user nayme. Sorry. I cannot reed your fortune. without this") ; // THE BOX WAS EMPTY
}
}
// <<<<<<<<<<<<<<<<<<<<<<<<< END SEND TWEETS <<<<<<<<<<<<<<<

Fonction GRABTWEETS() - c’est la fonction principale de récolte

// >>>>>>>>>>>>>>>>>>>>>>>>> GRAB THOSE TWEETS >>>>>>>>>>>>>

void grabTweets() {

color cl3 = color(70, 130, 180);
fill (cl3);
rect(0, (height/2)-120, width, 90);

fill(0, 25, 89, 255);
textSize(70);
text("Reading the collective mind...", (width/8)-120, (height/2)-50); // THE ALERT FOR UPDATE CHECKING PAUSE
loadRemoteAdminSettings(); // GET THE LATEST ADMIN FROM GOOGLE SPREADSHEET

//Credentials
ConfigurationBuilder cbTest = new ConfigurationBuilder();
// ------- NB - the variables twitOAuthConsumerKey, etc. ARE IN A SEPARATE SHEET
cbTest.setOAuthConsumerKey(twitOAuthConsumerKey);
cbTest.setOAuthConsumerSecret(twitOAuthConsumerSecret);
cbTest.setOAuthAccessToken(twitOAuthAccessToken);
cbTest.setOAuthAccessTokenSecret(twitOAuthAccessTokenSecret);

Twitter twitterTest = new TwitterFactory(cbTest.build()).getInstance();

try { // TRY ALLOWS ERROR HANDLING FOR EXCEPTIONS...
Query query = new Query(queryString); // this is default you check the first of 4 admin settings, but should be extended to include passing a selctor param
query.count(int(adminSettings[3])); // count is the number of tweets returned per page

QueryResult result = twitterTest.search(query); // gets the query

int ll=1; // DEBUG STUFF
for (Status status : result.getTweets()) { // EXTRACT THE TWEETS
String user = status.getUser().getScreenName();// GET THE TWITTER USERNAME
usernames.add(user); // ADD TO THE ARRAYLIST FOR USERNAMES
String msg = status.getText(); // EXTRACT THE TWEET TEXT
println ("tweet #"+ll); // DEBUG STUFF
println(" + user); // DEBUG STUFF
println("Text of tweet=" + status.getText()); // DEBUG STUFF
println ("-----------");
ll++; // DEBUG STUFF (INCREMENT)

//Break the tweet into words
String[] input = msg.split(" "); // BREAK DOWN THE TWEET USING SPACES AS A DELIMITER
for (int j = 0; j < input.length; j++) {

cleanTweets.add(input[j]); // CLEANTWEETS IS A STORE FOR TWEET WORDS WITH STOP WORDS REMOVED

for (int ii = 0 ; ii < stopWords.size(); ii++) {

if (stopWords.get(ii).equals(input[j])) {
cleanTweets.remove(input[j]); // THIS WORD IS A STOP WORD - REMOVE IT!
println("Word removed due to matched stopword: "+input[j]); // DEBUG STUFF
} // end if
} //end for (ii++) //stopword c
}// end clean this msg
}// end of all tweet cleaning
println ("cleanTweets = "+cleanTweets);

for (int k = 0; k < cleanTweets.size(); k++) {
if ((cleanTweets.get(k).equals(queryString))!= true)
{
println ("(cleanTweets.get(k) <"+cleanTweets.get(k)+".equals(queryString))"+queryString+"!= true");
words.add(cleanTweets.get(k));
if (words.size() >int(adminSettings[6]))
{
words.remove(0);
} // keeps aray to a finite length by dropping off first element as new one is added

// >>>>>> make the list of hashtags
String hashtag= cleanTweets.get(k);

String hashtagArray[] = hashtag.split("#");
if (hashtagArray.length>1)
{
//println ("inside checker");
hashtags.add(hashtagArray[1]);
int v=words.size()-1;
words.remove(v);
if (queryType.equals("hashtag"))
{
if (hashtagArray[1].equals("#"+queryString)) {
hashtags.remove(hashtagArray[1]);
}
else if (hashtags.size() >int(adminSettings[6])/10)
{
hashtags.remove(0);
} // keeps aray to a finite length by dropping off first element as new one is added
}
println ("hashtagArray["+k+"]= "+hashtagArray[1]);
}
// <<<<<<<

// >>>>>>> set up list of usernames
String username= cleanTweets.get(k);
String usernameArray[] = username.split("
// println ("usernameArray = ");
//println (usernameArray);
if (usernameArray.length>1)
{

int vv=words.size()-1; // takes out the username by removing last entry in words()
words.remove(vv);//
// println ("usernameArray["+j+"]= "+usernameArray[1]);
}
if (usernames.size() >int(adminSettings[6])/6)
{
usernames.remove(0);
} // keeps aray to a finite length by dropping off first element as new one is added

// <<<<<<<<

// >>>>>>>> set up urls >>>>>>
String url = cleanTweets.get(k);
String urlArray[] = url.split("h");
if (urlArray.length>1)
{
String urlArray2[] = urlArray[1].split("t");
if (urlArray2.length>2)
{
urls.add(url);
int vvv=words.size()-1;
words.remove(vvv);
}
else if (urls.size() >int(adminSettings[6])/6)
{
urls.remove(0);
} // keeps aray to a finite length by dropping off first element as new one is added

// <<<<<<<<<< end

// >>>>>>>>>>
}
};
}

println ("WORDS.SIZE () = "+words.size());
println ("words = "+words);
println ("
// >>>>>>> create text log file of words from pyschic scanning >>>>>>>>>
for (int p =0;p
{
uberWords = append (uberWords, words.get(p).toString());
}
uberWords = append (uberWords, "WORDS UPDATE REFRESH COMPLETED");
uberWords = append (uberWords, " ");
saveStrings ("words-"+stamp+".txt", uberWords);
// <<<<<< end word text log file

// >>>>>> create log file of users
for (int jj =0;jj

{
uberUsers = append (uberUsers, "

}
saveStrings ("users-"+stamp+".txt", uberUsers);
// <<<<<<<<< end user text log file

// >>>>>> create log file of hashtags
for (int jj =0;jj

{
uberHashtags = append (uberHashtags, "#"+hashtags.get(jj).toString());

}
saveStrings ("hashtags-"+stamp+".txt", uberHashtags);
// <<<<<<<<< end hashtag text log file

// >>>>>> create log file of urls
for (int jj =0;jj

{
uberUrls = append (uberUrls, urls.get(jj).toString());

}
saveStrings ("urls-"+stamp+".txt", uberUrls);
// <<<<<<<<< end url text log file

} //end try ??

catch(TwitterException e) {
println("TEST query tweet: " + e + " Status code: " + e.getStatusCode());
} // end try/catch

grabTime=millis(); // reset grabTime
if (loadSettingsFirstLoadFlag==true)
{
loadSettingsFirstLoadFlag =false; //
//this is the line that will cause subsequqnt updates to remove the first word(0)
}
cleanTweets.clear();
tweetster.clear();
} // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< end grabTweets() <<<<<<<<

Fonction BUTTONCHECK() - vérification de l’interaction

void buttonCheck(String tweetTextIntro)
{
if (b.isPressed()) {
println("button being pressed");
sendTweet ("digital (onscreen) Button MOUSE");
b.setWidth(50);
// action for onscreen button press
}
}
// <<<<<<<<<<<<<<<<<<<<<<< end of BUTTONCHECK

// >>>>>>>>>>>>>>> check the open serial port >>>>>>>>>>

Fonction CHECKSERIAL() - vérifie les données de l’Arduino

void checkSerial() {
println ();
//println ("inside checkSerial()");
try {
// >>>>>> see if the port is sending you stuff
while (port.available () > 0) {
String inByte = port.readString();
println ("Safe from OUSIDE IF . inByte = "+inByte);
int w=int(random(150));
b.setWidth(w);
println ();
port.clear();
sendTweet ("physical Button");
}
} // end try
catch (Exception e) {
println ("Check serial exception = "+e);
}
} // <<<<<<<<<<<<<<<<<<<<< end checkSerial <<<<<<<<<<<<<<<<<<<<<

// >>>>>>>>>>>>>>>>>>> load remote admin settings >>>>>>>>>>>>>>

Fonction LOADREMOTESETTINGS() - tire contrôle les données de Google spreadsheetsdata

void loadRemoteAdminSettings ()
{
try {
String checkRandomSpeech = adminSettings[8];
adminSettings = loadStrings("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdFNOcGtMaXZnS3IwdTJacllUT1hLQUE&output=txt");
if ((checkRandomSpeech.equals(adminSettings[8]))!=true) {
tts.speak(adminSettings[8]);
}
for (int i = 0 ; i < adminSettings.length; i++) {
println("adminSettings["+i+"]= "+adminSettings[i]);
} // end for

if (adminSettings[5].equals("h")) {
println ("use hashtag for search");
queryString = adminSettings[0];
queryType = "hashtag";
}
if (adminSettings[5].equals("u"))
{
println ("use username phrase for search");
queryString = adminSettings[1];
queryType = "username";
}
if (adminSettings[5].equals("s"))
{
println ("use search term for search");
queryString = adminSettings[2];
queryType = "search term";
}
updateDisplayVariables();
// now load load fortune fragments
String frag1 []= loadStrings ("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdDQ3cUZ5Y2RMTm9RSXNrdElZTjN5R1E&output=txt");
for (int ff1=0; ff1

{
fortFrags1.add(frag1[ff1]);
println ("Fortune Frag1 = "+fortFrags1.get(ff1));
}
String frag2 []= loadStrings ("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdGFQLTFhMUVqTTlkTjlRVUN4c3JtOGc&output=txt");
for (int ff2=0; ff2

{
fortFrags2.add(frag2[ff2]);
println ("Fortune Frag2 = "+frag2[ff2]);
println ("Fortune Frag1 = "+fortFrags2.get(ff2));
}
String frag3 []= loadStrings ("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdFE0Qm1yYmhyYWJETVJsSHJIOGFMQ3c&output=txt");
for (int ff3=0; ff3

{
fortFrags3.add(frag3[ff3]);
println ("Fortune Frag3 = "+frag3[ff3]);
}
String frag4 []= loadStrings ("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdG9KTnhLS2Zvbk5HNXp2RmRpeUZtTUE&output=txt");
for (int ff4=0; ff4

{
fortFrags4.add(frag4[ff4]);
println ("Fortune Frag4 = "+frag4[ff4]);
}
// end if
}
catch (Exception e) {
println ("no CONNECTION");
}
}

// >>>>

LOADREMOTESTOPWORDS() - importe la liste de filtres de mot vide

void loadRemoteStopWords ()
{
try {
String stopWordsLoader [] = loadStrings("https://docs.google.com/spreadsheet/pub?key=0AgTXh43j7oFVdFByYk41am9jRnRkeU9LWnhjZFJTOEE&output=txt");

if (loadstopWordsCheckInt==true)
{
for (int i = 0 ; i < stopWordsLoader.length; i++) {
//stop
stopWords.add(stopWordsLoader[i]);
println("stopWords["+i+"]= "+stopWords.get(i)+". Length now: "+stopWords.size());
}
loadstopWordsCheckInt=false;
}
}
catch (Exception e)
{
println("jjjjjjjjjjjjj");
}
}

Articles Liés

Diseuse de bonne aventure Madame K squelette

Diseuse de bonne aventure Madame K squelette

La diseuse de bonne aventure est contrairement à la plupart des machines de fortune teller en ce qu'il va vous insulter. Lorsque les enfants costumés frappent à la porte, ils sont toujours attirés la diseuse squelette. J'ai changer la fortune dosée e
Comment utiliser des diseuses de bonne aventure comme une aide à la révision.

Comment utiliser des diseuses de bonne aventure comme une aide à la révision.

En faisant « diseuses de bonne aventure », les étudiants révisera le vocabulaire principal et les faits d'une rubrique de votre choix.Plupart des gens savent comment faire des diseuses de bonne aventure, et la plupart des enseignants aura eu confisqu
Diseuse de bonne aventure multi-personnalité

Diseuse de bonne aventure multi-personnalité

Ce projet Arduino est un retour à plusieurs jeux d'arcade de carnaval et de la nouveauté de quand j'étais gamin. J'ai fait beaucoup de projets Arduino, mais il s'agit de mon premier projet qui a été ma propre conception. Avant cela, j'ai suivi généra
Charmes de diseuse de bonne aventure en bois

Charmes de diseuse de bonne aventure en bois

j'ai eu l'idée de poussière star du film, il s'agit d'une version miniature et je vais le faire bientôt la version pleine grande.vous aurez besoin :1) stylo couteau (ou couteau bien aiguisé)2) un fichier (pas une lime à ongles)3) un assortiment de cr
Diseuse de bonne aventure origami favorise

Diseuse de bonne aventure origami favorise

Ces faveurs sont une faveur rapide et facile, mais attrayante et populaire pour un mariage ou une fête. Ils ont fière allure sur la table et, selon quels messages vous mettez à l'intérieur, peuvent causer beaucoup hilarité ou chaudes lueurs floues, s
Fleurs de diseuse de bonne aventure faciles

Fleurs de diseuse de bonne aventure faciles

Ces fleurs fraîches et faciles sont bons à peu près rien ! Donner comme un cadeau ou de décoration pour la pièce maîtresse autour d'une table. Dans tous les cas ces fleurs sont faciles et rapides.Étape 1: Que vous faut-il ?Tout ce dont vous avez beso
Jouer avec la diseuse de bonne aventure ! :)

Jouer avec la diseuse de bonne aventure ! :)

je vais vous montrer comment jouer avec une diseuse de bonne aventure origami:)Étape 1: Écrit:) après que vous avez fait faire la fortune vous dire devez écrire les fortunes sur elle et un peu d'autres choses. du côté sortie volets vous mettre les do
Diseuse de bonne aventure en origami ! :)

Diseuse de bonne aventure en origami ! :)

une bonne chose à enseigner à vos enfants comment faire donc ils peuvent jouer avec leurs amis et leur dire leur fortune:DÉtape 1: matériaux vous aurez besoin - papier carrée. (tout type)-surface plane. (jusqu'à ce que vous obtenez assez bon sans en
Diseuse de bonne aventure Arduino

Diseuse de bonne aventure Arduino

ce projet donne à l'utilisateur une fortune et chanceux comme numéro d'un fortune cookie. Ceci a été rendu comme cadeau de Noël.Étape 1: Étape 1 Soudure des broches d'en-tête sur le LCD. Souder les fils aux broches femelle en-tête et ordonnées pour A
DIY diseuse de bonne aventure

DIY diseuse de bonne aventure

il s'agit d'un métier vraiment simple et facile pour tout le monde. Vous pouvez le faire sur le pouce, dans votre maison, ou en avion long manèges/voiture. C'est amusant car il existe de nombreuses variantes pour les fortunes réelles et vous devrez e
Diseuse de bonne aventure

Diseuse de bonne aventure

si vous ne savez pas comment faire une diseuse de bonne aventure, alors voici un moyen facile.Étape 1: pliage Obtenir un morceau carré de papier plier le papier en demi plier en deux à nouveau l'ouvrir puis pliez la vers l'intérieur des coins Retourn
Comment... Faire une diseuse de bonne aventure ! Je vous promets que c’est génial !

Comment... Faire une diseuse de bonne aventure ! Je vous promets que c’est génial !

Étape 1 : Vous aurez besoin d'un morceau de papier, 4 crayons de couleur différente, des crayons ou des marqueurs, ciseaux, un crayon.Étape 2 : Prenez votre morceau de papier et pliez-la comme un voilier.Étape 3 : Maintenant où le pli est, couper en
Comment faire un receveur cootie / diseuse de bonne aventure

Comment faire un receveur cootie / diseuse de bonne aventure

Instructions1. trouver un ami et demandez-lui de penser à une question à poser la diseuse de bonne aventure. Ainsi, « j'ai passera mon test » ?2. maintenant amener à choisir une couleur, écrite sur un des côtés. Préciser la couleur qu'ils ont choisi,
Comment faire une diseuse de bonne aventure tour

Comment faire une diseuse de bonne aventure tour

c'est une façon de faire un truc diseuse de bonne aventure que vous pouvez choisir s'il faut donner une mauvaise fortune, ou une bonne fortune.Vous aurez besoin :PapierOutil d'écritureÉtape 1: pliage Replier les coins vers le centre, tourner sur le p