/* title */
/* 07 September 11:28 UTC 2024 */
#include <Arduino.h>
#include "bitmaps.h"
#include <AccelStepper.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <MultiStepper.h>
#include <Servo.h>
// Pin für Morsecode-Eingabe
// Create a struct for Morse code mappings
struct MorseMapping {
const char *code;
char character;
};
#define SCREEN_WIDTH 128 // Breite des OLED-Displays in Pixeln
#define SCREEN_HEIGHT 64 // Höhe des OLED-Displays in Pixeln
#define OLED_RESET -1 // Reset-Pin (oder -1, wenn Arduino-Pin verwendet wird)
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Servo leftArmServo;
Servo rightArmServo;
char commandBuffer[50]; // Global command buffer-.
const int ARM_SERVO_LEFT_PIN = 2;
const int ARM_SERVO_RIGHT_PIN = 3;
const int TRIGGER_PIN = 4;
const int ECHO_PIN = 5;
const int BUZZER_PIN = 6;
const int LEFT_MOTOR_FORWARD_PIN = 7;
const int LEFT_MOTOR_BACKWARD_PIN = 8;
const int RIGHT_MOTOR_FORWARD_PIN = 9;
const int RIGHT_MOTOR_BACKWARD_PIN = 10;
const int MORSE_INPUT_PIN = 11;
enum Emotion { HAPPY, SAD, ANGRY, NEUTRAL };
Emotion currentEmotion = NEUTRAL;
// bitmaps removed from here
// Custom Morse code mapping
const MorseMapping morseMappings[] = {
{".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'},
{".", 'E'}, {"..-.", 'F'}, {"--.", 'G'}, {"....", 'H'},
{"..", 'I'}, {".---", 'J'}, {"-.-", 'K'}, {".-..", 'L'},
{"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'},
{"--.-", 'Q'}, {".-.", 'R'}, {"...", 'S'}, {"-", 'T'},
{"..-", 'U'}, {"...-", 'V'}, {".--", 'W'}, {"-..-", 'X'},
{"-.--", 'Y'}, {"--..", 'Z'}, {"-----", '0'}, {".----", '1'},
{"..---", '2'}, {"...--", '3'}, {"....-", '4'}, {".....", '5'},
{"-....", '6'}, {"--...", '7'}, {"---..", '8'}, {"----.", '9'}};
const int numMappings = sizeof(morseMappings) / sizeof(morseMappings[0]);
/* ******************************************
* function()
/* **************************************** */
unsigned char readkey(void) {
unsigned char ret = 0;
if (digitalRead(8) == LOW)
ret = 1;
if (digitalRead(9) == LOW)
ret = 2;
if (digitalRead(10) == LOW)
ret = 3;
if (digitalRead(11) == LOW)
ret = 4;
return ret;
}
/* ******************************************
* function()
/* **************************************** */
void updateEyes() {
static int xp = 16;
static int mood = 1;
static int xd = 0, espera = 0, step = 0;
if (step == 0) {
display.clearDisplay();
display.drawBitmap(xp, 0, neutral_bitmap, 32, 32,
WHITE); // Beispiel; ändern entsprechend
display.display();
step = 1;
} else {
espera++;
if (espera == 3) {
espera = 0;
step = 0;
}
}
int n = readkey();
if (n == 2)
xp = (xp <= 0 ? 0 : xp - 1);
if (n == 4)
xp = (xp >= 32 ? 32 : xp + 1);
if (n == 1) {
mood = (mood >= 5 ? 0 : mood + 1);
do {
} while (readkey() != 0);
}
if (n != 0) {
espera = 0;
step = 0;
}
}
/* ******************************************
* function()
/* **************************************** */
unsigned int readUltrasonicDistance() {
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
unsigned long duration = pulseIn(ECHO_PIN, HIGH);
unsigned int distance = duration / 29 / 2;
return distance;
}
/* ******************************************
* function()
/* **************************************** */
void moveForward() {
digitalWrite(LEFT_MOTOR_FORWARD_PIN, HIGH);
digitalWrite(LEFT_MOTOR_BACKWARD_PIN, LOW);
digitalWrite(RIGHT_MOTOR_FORWARD_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_BACKWARD_PIN, LOW);
Serial.println("Vorwärts bewegen...");
}
/* ******************************************
* function()
/* **************************************** */
void moveBackward() {
digitalWrite(LEFT_MOTOR_FORWARD_PIN, LOW);
digitalWrite(LEFT_MOTOR_BACKWARD_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_FORWARD_PIN, LOW);
digitalWrite(RIGHT_MOTOR_BACKWARD_PIN, HIGH);
Serial.println("Rückwärts bewegen...");
}
/* ******************************************
* function()
/* **************************************** */
void stopMovement() {
digitalWrite(LEFT_MOTOR_FORWARD_PIN, LOW);
digitalWrite(LEFT_MOTOR_BACKWARD_PIN, LOW);
digitalWrite(RIGHT_MOTOR_FORWARD_PIN, LOW);
digitalWrite(RIGHT_MOTOR_BACKWARD_PIN, LOW);
Serial.println("Bewegung gestoppt...");
}
/* ******************************************
* function()
/* **************************************** */
void displayEmotionBitmap(Emotion emotion) {
display.clearDisplay();
switch (emotion) {
case HAPPY:
display.drawBitmap(0, 0, happy_bitmap, 128, 64, WHITE);
break;
case SAD:
display.drawBitmap(0, 0, sad_bitmap, 128, 64, WHITE);
break;
case ANGRY:
display.drawBitmap(0, 0, angry_bitmap, 128, 64, WHITE);
break;
case NEUTRAL:
display.drawBitmap(0, 0, neutral_bitmap, 128, 64, WHITE);
break;
}
display.display();
}
/* ******************************************
* function()
/* **************************************** */
void moveArms(Servo &leftServo, Servo &rightServo, int angle) {
leftServo.write(angle);
rightServo.write(angle);
delay(500);
}
/* ******************************************
* function()
/* **************************************** */
void expressEmotion(Emotion emotion) {
switch (emotion) {
case HAPPY:
displayEmotionBitmap(HAPPY);
moveArms(leftArmServo, rightArmServo, 90);
delay(1000);
moveArms(leftArmServo, rightArmServo, 0);
currentEmotion = HAPPY;
break;
case SAD:
displayEmotionBitmap(SAD);
currentEmotion = SAD;
break;
case ANGRY:
displayEmotionBitmap(ANGRY);
currentEmotion = ANGRY;
break;
case NEUTRAL:
displayEmotionBitmap(NEUTRAL);
currentEmotion = NEUTRAL;
break;
}
}
/* ******************************************
* function()
/* **************************************** */
void sayYes() {
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
}
/* ******************************************
* function()
/* **************************************** */
void sayNo() {
for (int i = 0; i < 2; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(300);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
}
/* ******************************************
* function()
/* **************************************** */
void morseCodeInterpreter(char character) {
switch (character) {
case 'A':
expressEmotion(HAPPY);
Serial.println(F("Morsecode interpretiert: A (Glücklich)"));
break;
case 'B':
expressEmotion(SAD);
Serial.println(F("Morsecode interpretiert: B (Traurig)"));
break;
case 'C':
expressEmotion(ANGRY);
Serial.println(F("Morsecode interpretiert: C (Wütend)"));
break;
case 'D':
expressEmotion(NEUTRAL);
Serial.println(F("Morsecode interpretiert: D (Neutral)"));
break;
default:
Serial.println(F("Unbekannter Morsecode"));
break;
}
}
/* ******************************************
* function()
/* **************************************** */
void reactToCommand(String command) {
if (command.equalsIgnoreCase("Loki")) {
expressEmotion(HAPPY);
Serial.println(F("Hallo, Loki!"));
} else if (command.equalsIgnoreCase("ja")) {
sayYes();
} else if (command.equalsIgnoreCase("nein")) {
sayNo();
} else if (command.equalsIgnoreCase("vorwärts")) {
moveForward();
} else if (command.equalsIgnoreCase("rückwärts")) {
moveBackward();
} else if (command.equalsIgnoreCase("stop")) {
stopMovement();
} else {
morseCodeInterpreter(command[0]);
}
}
/* ******************************************
* function()
/* **************************************** */
String readSerialInput() {
int index = 0;
while (Serial.available() > 0 && index < sizeof(commandBuffer) - 1) {
char c = Serial.read();
if (c == '\n') {
break;
}
commandBuffer[index++] = c;
}
commandBuffer[index] = '\0'; // Nullterminierung des Strings
return String(commandBuffer);
}
/* ******************************************
* function()
/* **************************************** */
void avoidObstacle() {
unsigned int distance = readUltrasonicDistance();
if (distance < 10) {
stopMovement();
moveBackward();
delay(500);
stopMovement();
delay(500);
moveForward();
} else {
moveForward();
}
}
/* ******************************************
* function()
/* **************************************** */
String readMorseInput() {
return ""; // Platzhalter für Morse-Eingabelesen
}
/* ******************************** MAIN ********************** */
/* ******************************************************
* setup
****************************************************** */
void setup() {
Serial.begin(115200);
// OLED Display initialisieren
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Endlosschleife bei Fehler
}
display.display();
delay(2000);
display.clearDisplay();
// Servos für Arme initialisieren
leftArmServo.attach(ARM_SERVO_LEFT_PIN);
rightArmServo.attach(ARM_SERVO_RIGHT_PIN);
// Pins für Motoren, Ultraschallsensor und Augensteuerung initialisieren
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LEFT_MOTOR_FORWARD_PIN, OUTPUT);
pinMode(LEFT_MOTOR_BACKWARD_PIN, OUTPUT);
pinMode(RIGHT_MOTOR_FORWARD_PIN, OUTPUT);
pinMode(RIGHT_MOTOR_BACKWARD_PIN, OUTPUT);
pinMode(MORSE_INPUT_PIN, INPUT);
pinMode(8, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
Serial.println(F("Setup abgeschlossen"));
}
/* ******************************************
* loop
****************************************** */
void loop() {
avoidObstacle();
unsigned int distance = readUltrasonicDistance();
Serial.print(F("Entfernung: "));
Serial.print(distance);
Serial.println(F("cm"));
String command = readSerialInput();
if (command.length() > 0) {
reactToCommand(command);
}
String morseCode = readMorseInput();
if (morseCode.length() > 0) {
char interpretedChar = '\0';
for (int i = 0; i < numMappings; ++i) {
if (strcmp(morseMappings[i].code, morseCode.c_str()) == 0) {
interpretedChar = morseMappings[i].character;
break;
}
}
if (interpretedChar != '\0') {
Serial.print("Morse Code: ");
Serial.print(morseCode);
Serial.print(" -> Character: ");
Serial.println(interpretedChar);
morseCodeInterpreter(interpretedChar);
} else {
Serial.print("Unbekannter Morsecode: ");
Serial.println(morseCode);
}
}
updateEyes();
delay(100); // Je nach benötigter Reaktionszeit anpassen
}
/* end */