De echte Halfzware uit Friesland!
Weerstation

Arduino Projecten

Arduino is een opensource-computerplatform dat is opgebouwd rond de ATmega168-microcontroller van Atmel en het softwareontwikkelplatform Processing. Dit platform is bedoeld voor hobbyisten, artiesten, kunstenaars en iedereen die geïnteresseerd is in het maken en ontwerpen van slimme en creatieve objecten die kunnen reageren op hun omgeving.

Arduinofoon/Wonderfoon

De Arduinofoon is een oude PTT telefoon die is omgebouwd tot mini-jukebox met behulp van een Arduino Uno microcontroller en een MP3 speler. Als je de hoorn van de haak neemt hoor je de kiestoon en als je daarna een nummer kiest tussen de 0 en de 9 hoor je vervolgens een muziekje.

Hieronder de code…

/*
De Arduinofoon.
Een MP3 speler ingebouwd in een ouderwetse PTT kiesschijftelefoon type T65.
Elk gedraaid nummer laat een MP3 melodie horen.
Bij opnemen van de hoorn klinkt de kiestoon.
Afgeleid van de wonderfoon met Raspberry PI3 maar nu met een Arduino UNO R3.
Zie bijbehorend aansluitschema met technische gegevens Arduinofoon 1.5.
Softwareversie 1.4a.
Alex Pikkert Mei 2019.
MP3 speler aansluitingen:
pin 2 next
pin 4 previous
pin 5 repeat
pin 6 pause
pin 12 5 Volt power MP3 speler ON/OFF via schakeltransistor.
*/
#include <EEPROM.h>
int dialHasFinishedRotatingAfterMs = 100;
int debounceDelay = 10;
int needToSend = 0;
int count; // dit is de variable waar de kiesschijf keuze ( 1 tot 0 wordt 1 tot 10) in vastgelegd wordt.
int lastState = LOW;
int trueState = LOW;
long lastStateChangeTime = 0;
int reading = 0;
int address = 3; // het EEPROM adres waar het songnummer opgeslagen wordt.
int lastSong; // opgeslagen songnummer in EEPROM.
int i; // teller hoeveel keer de MP3 speler vooruit of achteruit gezet moet worden.
int j; // teller welke actuele song gedraaid is met de kiesschijf.
int dialtoneOut = 7; // de uitgang met een 425 Herz kiestoon. Let op: pin 3 en 11 NIET gebruiken. (Zie "tone" uitleg op de Arduino reference site).
int hookContact = 8; // contact gesloten (LOW) als de hoorn van de haak genomen is.
int dialEnabled = 9; // contact gesloten (LOW) als de kiesschijf actief is.
int dialPulses = 10; // contact gesloten LOW) en alleen open als er een puls gegenereerd wordt.
int mp3Power = 12; // als deze poort HIGH is dan is de MP3 speler aan.
//******************************************************************************************
void setup()
{
pinMode(dialPulses, INPUT_PULLUP); // ingang voor het pulscontact van de kiesschijf.
pinMode(dialEnabled, INPUT_PULLUP); // ingang voor het contact van de kieschijf als die geactiveerd is.
pinMode(hookContact, INPUT_PULLUP); // ingang voor het contact van de telefoonhoorn opgenomen/neergelegd.
// PULLUP is nodig om instabiele ingang te voorkomen bij geopend en dus zwevend contact.
// als een contact open is wordt de ingang hooggehouden (HIGH) door de interne pullup weerstand van de Arduino.
pinMode(mp3Power,OUTPUT); // deze poort is 0 of 5 volt om de MP3 speler uit- of in te schakelen.
if (digitalRead(hookContact) == LOW) // als de hoorn opgenomen is doe het volgende:
{
mp3PowerON(); // zet de MP3 speler aan.
delay(2500); //wacht even tot de MP3 speler gestart is.
pause(); // zet de MP3 speler op pauze.
tone(dialtoneOut,425); // zet de kiestoon aan.
}
}
//******************************************************************************************
void loop()
{
// als de kiesschijf actief is, detecteer het nummer en zet de kiestoon uit.
// als de kiesschijf in rust is, selecteer de song door de MP3 speler vooruit of achteruit te zetten.
// als de hoorn op de haak gelegd wordt ga dan in de wachtlus en zet indien nodig de kiestoon uit.
if (digitalRead(dialEnabled) == LOW){numberDialed();noTone(dialtoneOut);}
else{selectSong();}
if (digitalRead(hookContact) == HIGH){mp3Wait();}
}
//subroutines ******************************************************************************************
// zet de MP3 speler vooruit of achteruit afhankelijk van het verschil tussen vorige en de actuele song.
void selectSong()
{
switch (count) {
case 1:j=1;Song();break;
case 2:j=2;Song();break;
case 3:j=3;Song();break;
case 4:j=4;Song();break;
case 5:j=5;Song();break;
case 6:j=6;Song();break;
case 7:j=7;Song();break;
case 8:j=8;Song();break;
case 9:j=9;Song();break;
case 10:j=10;Song();break;
default:
// als de waarde nergens past, voer dan de default instructie uit.
// de default instructie is optioneel.
break;
}
}
// ga naar de actuele song.
void Song()
{
lastSong = EEPROM.read(address); // opgeslagen songnummer van de vorige song.
if(lastSong == j){next();prev();} // als zelfde nummer gekozen is ga dan toch afspelen.
EEPROM.update(address, j); // sla de actuele song op in het geheugen.
if(lastSong <j){for (i=lastSong;i<j;i++){next();}} // ga het verschil tussen de vorige en actuele song verder.
if(lastSong >j){for (i=j;i<lastSong;i++){prev();}} // ga het verschil tussen de vorige en actuele song terug.
delay(400);repeat(); delay(5000); // wacht even en geef dan een repeat commando zodat steeds dezelfde song gespeeld wordt.
}
// besturing van de MP3 speler.
void next()
{pinMode(2,OUTPUT); delay( 200);pinMode(2,INPUT);delay(400);count=0;}
void prev()
{pinMode(4,OUTPUT); delay(200);pinMode(4,INPUT);delay(400);count=0;}
void repeat()
{pinMode(5,OUTPUT); delay(200);pinMode(5,INPUT);delay(400);count=0;}
void pause()
{pinMode(6,OUTPUT); delay(200);pinMode(6,INPUT);delay(400);count=0;}
// zet de MP3 speler uit.
void mp3PowerOFF()
{digitalWrite(mp3Power,LOW);}
// zet de MP3 speler aan.
void mp3PowerON()
{digitalWrite(mp3Power,HIGH);}
// wachtlus als de hoorn op de haak gelegd wordt. kiestoon gaat uit en als hoorn opgenomen wordt dan volgt een soft reset.
void mp3Wait()
{noTone(dialtoneOut);mp3PowerOFF();
while(digitalRead(hookContact)==HIGH){} ;
asm volatile (" jmp 0");
}
// detectie van het gekozen nummer, vastgelegd in de variabele count.
void numberDialed()
{
reading = digitalRead(dialPulses);
if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs)
{if (needToSend==1) {needToSend = 0;count = 0;}
}
if (reading != lastState) {lastStateChangeTime = millis();}
if ((millis() - lastStateChangeTime) > debounceDelay)
{if (reading != trueState)
{trueState = reading;if (trueState == HIGH) {count++;needToSend = 1;}
}
}
lastState = reading;
}

Deze onderdelen heb je nodig:

  • 1 draaischijftelefoon type T65
  • meeraderig montagedraad in verschillende kleuren
  • krimpkous 4 mm doorsnede
  • 1 Arduino UNO R3 (een originele of een kloon kan ook)
  • 1 MP3 speler type FN-M981
  • 1 voedingsplug 9-12 Volt minimaal 1 Ampère met 2,1mm ronde steker
  • 1 micro SD kaartje voor de muziek (1 Gb is meer dan voldoende)
  • 1 SD kaarthouder om het micro SD kaartje op de PC te kunnen aansluiten
  • 6 weerstanden 1 kOhm 1/8 Watt
  • 1 weerstand 22 kOhm 1/8 watt
  • 1 transistor type BC547
  • 1 condensator 1uf
  • 1 DC contrasteker 2,1 mm met bedrading
  • 1 DC steker 2,1 mm met bedrading
  • 1 zekeringhouder met een glaszekering 1A traag voor inbouw in bedrading
  • 1 rijtje aansluitpinnetjes voor de Arduino UNO
  • 1 stukje experimenteerprint 6×8 gaatjes 0,1 inch afstand met eilandjes koper
  • 1 plaatje hardboard volgens tekening, 3,2 mm dik
  • 2 M3 boutjes 10 mm lang
  • 2 M3 boutjes 20 mm lang
  • 4 M3 moertjes
  • 2 M5 moeren, gebruikt als afstandshouders
  • dubbelzijdig plakband

Het schema


Prototype Arduino Weerstation

Proto

Prototype op een breadboard

Als geheugensteuntje voor me zelf…

De uiteindelijke uitvoering zoals het moet worden…

Wat hebben we nodig voor deze klus:

1 X Arduino Uno
1 X ESP8266 Wifi-module
1 X DHT22 temperatuur en luchtvochtigheidssensor
1 X Barometer-sensor
2 x LED Display – 7-segment module
2 X Blauwe LED
2 X Weerstand 100 Ω
1 X 3,3 volt spanningsregelaar (voor de ESP8266)


Het arduino weerstation is online…

Hier de tijdelijke code voor de Arduino:

#include<stdlib.h>                 //voor strings
#include <Arduino.h>
#include <DHT.h>
#include <Adafruit_BMP085.h>
#include <SoftwareSerial.h>

#include "SevenSegmentTM1637.h"
#define DEBUG 0                                     // change value to 1 to enable debuging using serial monitor

String IP = "184.106.153.149"; // ThingSpeak IP Address: 184.106.153.149
String GET = "GET /update?key=XXXXXXXXXXXXX";    // replace with your channel key
int count = 1;

long previousMillis = 0;        // will store last time Thingspeak was updated
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 300000;           // interval at which to update (milliseconds) (5 minuten)


float temp;
float p;
float hum;
int h;

#define CLK 2
#define DIO 3

#define CLL 4
#define DIP 5

#define DHTTYPE DHT22   // DHT 11
#define DHTPIN 8     // what digital pin is DHT connected to
#define BLED 12      // Blauwe LED   pinMode(BLED, OUTPUT); //initialiseer pin 12 (BLAUWE LED).
#define WLED 11

Adafruit_BMP085 bmp;
DHT dht(DHTPIN, DHTTYPE);
SevenSegmentTM1637 tm1637(CLK, DIO);
SevenSegmentTM1637 tm1638(CLL, DIP);
//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//0~9,A,b,C,d,E,F
SoftwareSerial mySerial(7, 6); // RX, TX

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  mySerial.begin(9600);
  delay(1000);

  tm1637.setBacklight(30);  // set the brightness to 100 %
  tm1638.setBacklight(30);  // set the brightness to 100 %


  delay(300); // Pauze om sensor stabiel te laten worden
  if (DEBUG) {
    Serial.println("Klaar om te beginnen...\r\n");
  }
  delay(700); // Nog een pauze (in totaal is 1sec nodig)

  if (!bmp.begin()) {
    if (DEBUG) {
      Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    }
    while (1) {}
  }
  resetWiFi();
  tm1637.begin();            // initializes the display
  tm1637.print("INIT");      // display INIT on the display
  tm1638.begin();            // initializes the display
  tm1638.print("INIT");      // display INIT on the display

  delay(1000);
}

void loop() {
  byte  rawData;
  int disptemp;
  int har;
  int vocht;

  // put your main code here, to run repeatedly:

  //************************************************************************
  //*********** Temperatuur op display1 ************************************

  unsigned long currentMillis = millis();

  temp = dht.readTemperature();
  hum = dht.readHumidity();
  vocht = hum * 100;
  har = temp * 100;
  if (DEBUG) {
    Serial.print("Temp gelezen: ");
    Serial.println(temp);
    Serial.print("Vocht bewerkt:");
    Serial.println(vocht);
  }

  tm1637.clear();

  tm1637.setColonOn(1);
  rawData = B11100011;

  if (temp < 10)
  {
    tm1637.setCursor(0, 1);
  }
  else
  {
    tm1637.setCursor(0, 0);
  }
  if (temp < 0)
  {
    tm1637.setCursor(0, 0);
  }
  tm1637.print(har);
  tm1637.printRaw(rawData, 3);

  //*************************************************************************
  //*********  LUCHTDRUK op Display 2 ***************************************

  h = bmp.readPressure() / 100;
  for (int i = 0; i <= 4; i++) {
    tm1638.clear();
    tm1638.setColonOn(0);
    tm1638.print(h);

    delay(2000);
    // ******* En VOCHT ********************************************************
    tm1638.clear();
    tm1638.setColonOn(1);
    tm1638.print(vocht);
    //**************************************************************************
    //digitalWrite(BLED, HIGH);
    if (DEBUG) {
      Serial.println(i);
    }
    delay(2000);

  } //Einde FOR LOOP
  //**************************************************************************
  //**************************************************************************

  if (currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    digitalWrite(BLED, HIGH);         //Even laten zien dat we data uploaden...
    
    String cmd = "AT+CIPSTART=\"TCP\",\"";// Setup TCP connection
    cmd += IP;
    cmd += "\",80";
    mySerial.println(cmd);
    delay(5000);
    if (mySerial.find("Error")) {
      if (DEBUG) {
        Serial.println("ERROR while SENDING");
      }
      digitalWrite(WLED, LOW);
      resetWiFi();
      return;
    }
    cmd = GET + "&field1=" + String(temp) + "&field2=" + String(hum) + +"&field3=" + String(h) + "\r\n";
    mySerial.print("AT+CIPSEND=");
    mySerial.println(cmd.length());
    delay(15000);
    if (mySerial.find(">"))
    {
      mySerial.print(cmd);
      if (DEBUG) {
        Serial.println("Data sent");
      }
    } else
    {
      mySerial.println("AT+CIPCLOSE");
      if (DEBUG) {
        Serial.println("Connection closed");
      }
    }
    digitalWrite(BLED, LOW);
  }

  //**************************************************************************


}

void clearRXbuffer() {
  while (mySerial.available()) {
    char c = mySerial.read();
    //Serial.write(c);
    delay(3);
  }
}

void sendWiFi(String s, bool clearBuffer) {
  mySerial.println(s);
  mySerial.println("");
  delay(100);

  if (clearBuffer) clearRXbuffer();
}

void resetWiFi() {
  unsigned long timout = 0 ;
  digitalWrite(WLED, LOW);
  Serial.println ("WiFi Reset ");
  // Wait for an IP address (WIFI GOT IP)
  char c, buffer[25];
  int i = 0, w = 0;

  do {
    if (millis() > timout) {
      clearRXbuffer();
      timout = millis() + 20000;
      delay(1000);
      sendWiFi("AT+RST", true);
    }

    if (mySerial.available()) {
      c = mySerial.read();
      if (c == 'W' || i >= 20) i = 0;
      if (c > 9 && c < 91) {
        buffer[i++] = c;
      }
    } //else displayLoop(w++);

    if (w > 11) w = 0;

  } while (strstr(buffer, "WIFI GOT IP") == NULL);

  digitalWrite(WLED, HIGH);
}

 


Arduino Bluetooth Tank


 

 

Tank XL

Deze “Bluetooth Tank” is gebouwd naar een idee en ontwerp van Bart Venneker.
Meer leuke projecten en tutorials vind je op zijn website http://www.bartvenneker.nl

Zie hier zijn tutorial over het bouwen van deze tank:

 

De Arduino programmacode:

//
// Bart Venneker 2016
// Bluetooth RC Car
// see http://www.bartvenneker.nl/Arduino/index.php?art=0020 for details
// released into the public domain
//
#include <SoftwareSerial.h>
#define L298N_IN1 7
#define L298N_IN2 6
#define L298N_IN3 5
#define L298N_IN4 4
#define horn 8
#define lightFront 9
#define lightRear 10
#define blinkerRight 11
#define blinkerLeft 12
// Use softserial so we can use the hardware serial for debugging if needed
SoftwareSerial mySerial(2, 3); // RX, TX
void setup() {
 pinMode(blinkerLeft,OUTPUT);
 pinMode(blinkerRight,OUTPUT);
 pinMode(lightFront,OUTPUT);
 pinMode(lightRear,OUTPUT);
 pinMode(horn,OUTPUT);
 pinMode(L298N_IN1,OUTPUT);
 pinMode(L298N_IN2,OUTPUT);
 pinMode(L298N_IN3,OUTPUT);
 pinMode(L298N_IN4,OUTPUT);
mySerial.begin(9600);
 tone(horn,1000);delay(60);
 tone(horn,800);delay(80);
 noTone(horn);
 }
// Global variables
int dta=0;
int freq;
unsigned long blinkTimer = millis();
unsigned long sireneTimer = millis();
boolean blinker = true;
boolean alarmLights = false;
boolean blinkLeft;
boolean blinkRight;
boolean sirene=false;
void loop() {
 
 // read all data from the serial buffer
 while(mySerial.available() > 0){ 
 int a = mySerial.read() ; 
 if ( a > 13 ) dta = a; // ignore the carriage return character
 delay(2); // wait for more data
 }
 
 switch (dta) {
 case 'S': 
 driveTracks(0,0,0,0); setBlinker(0,0); break; // STOP the car
 case 'F':
 driveTracks(0,1,0,1); setBlinker(0,0); break; // Forward
 case 'B':
 driveTracks(1,0,1,0); setBlinker(0,0); break; // Reverse
 case 'L':
 driveTracks(1,0,0,1); setBlinker(0,1); break; // Left
 case 'R': 
 driveTracks(0,1,1,0); setBlinker(1,0); break; // Right
 case 'G':
 driveTracks(0,0,0,1); setBlinker(0,1); break; // Forward and Left
 case 'I':
 driveTracks(0,1,0,0); setBlinker(1,0); break; // Forward and Right
 case 'H': 
 driveTracks(0,0,1,0); setBlinker(0,1); break; // Backward and Left
 case 'J': 
 driveTracks(1,0,0,0); setBlinker(1,0); break; // Backward and Right
 case 'V': 
 sirene=true; break; // Sirene on
 case 'v':
 sirene=false; break; // Sirene off
 case 'W':
 digitalWrite(lightFront,1); break; // Head lights on
 case 'w':
 digitalWrite(lightFront,0); break; // Head lights off
 case 'U':
 digitalWrite(lightRear,1); break; // Rear lights on
 case 'u':
 digitalWrite(lightRear,0); break; // Rear lights off
 case 'X':
 alarmLights = true; break; // Warning lights on
 case 'x':
 alarmLights = false; break; // Warning lights off 
 }
 
 // This is to control the blinking speed, and drive the blinker lights
 if (millis()-blinkTimer > 250) {
 blinkTimer = millis(); 
 blinker = !blinker; 
 if (blinkLeft | alarmLights) digitalWrite(blinkerLeft,blinker);
 else digitalWrite( blinkerLeft,LOW);
 if (blinkRight | alarmLights) digitalWrite( blinkerRight,blinker);
 else digitalWrite( blinkerRight,LOW);
 }
// This is to control the sirene 
 if (millis()- sireneTimer > 400) {
 sireneTimer=millis();
 if (freq==700) freq=1000;
 else {freq=700; noTone(horn);}
 if (sirene) tone(horn,freq);
 }
}
void driveTracks(bool IN1,bool IN2,bool IN3,bool IN4) {
 digitalWrite(L298N_IN1,IN1);
 digitalWrite(L298N_IN2,IN2);
 digitalWrite(L298N_IN3,IN3);
 digitalWrite(L298N_IN4,IN4); 
}
void setBlinker(bool Right,bool Left){
 blinkLeft = Left;
 blinkRight = Right;
}

Hieronder de Android App voor de besturing…

bluetooth_rc_controller

Zie hier de eerste stapjes van mijn prototype:

En hier de HUD die ik  heb gemaakt voor het filmpje…

Nu de verlichting nog even…

Verlichting_BtTank

 

Tankverlichting