Devices & Components
1
Camera Flange 2.0 Version for myCobot
1
myCobot 280 M5Stack 2023 - 6 DOF Collaborative Robot
1
myCobot Adaptive Gripper
Hardware & Tools
1
Screwdriver (Phillips)
Software & Tools
1
Python 3
Arduino IDE
Project description
Code
Code arduino
cpp
...
1/* 2Human vs Robot – Rock Paper Scissors Interactive Game with MyCobot 280 & M5Stack by mirecemk 3 Python + Arduino real-time interaction! 4*/ 5 6#include <M5Stack.h> 7#include <MyCobotBasic.h> 8 9// ===================== CONFIG ===================== 10#define SERVO_SPEED 70 // doubled speed (was ~35) 11#define SPEAKER_PIN 25 // M5Stack Basic speaker (DAC1) 12#define DAC_VOL_HI 160 13#define DAC_VOL_LO 0 14 15// ===================== SOUND (DAC-safe) ===================== 16static inline void initSpeaker() { 17 pinMode(SPEAKER_PIN, OUTPUT); 18 dacWrite(SPEAKER_PIN, DAC_VOL_LO); 19} 20static inline void stopTone() { dacWrite(SPEAKER_PIN, DAC_VOL_LO); } 21 22static inline void playTone(int freq, int duration_ms) { 23 if (freq <= 0 || duration_ms <= 0) { stopTone(); delay(duration_ms); return; } 24 const uint32_t total_us = (uint32_t)duration_ms * 1000UL; 25 const uint32_t half_period_us = 500000UL / (uint32_t)freq; 26 if (half_period_us == 0) { stopTone(); delay(duration_ms); return; } 27 const uint32_t t_start = micros(); 28 while ((micros() - t_start) < total_us) { 29 dacWrite(SPEAKER_PIN, DAC_VOL_HI); 30 delayMicroseconds(half_period_us); 31 dacWrite(SPEAKER_PIN, DAC_VOL_LO); 32 delayMicroseconds(half_period_us); 33 yield(); 34 } 35 stopTone(); 36} 37 38static inline void countdownBeep(int n) { 39 const int f = (n == 3) ? 1200 : (n == 2) ? 1000 : 800; 40 playTone(f, 180); 41} 42static inline void shootSound() { playTone(1500, 120); delay(60); playTone(1700, 120); } 43static inline void victorySound() { playTone(523,160); delay(60); playTone(659,160); delay(60); playTone(784,220); } 44static inline void defeatSound() { playTone(784,160); delay(60); playTone(659,160); delay(60); playTone(523,220); } 45static inline void tieSound() { playTone(1000,120); delay(80); playTone(1000,120); } 46static inline void selectSound() { playTone(900,80); } 47static inline void clickSound() { playTone(700,60); } 48 49// ===================== ROBOT / GAME LOGIC ===================== 50MyCobotBasic myCobot; 51 52enum GameState { READY, COUNTDOWN, REVEAL, RESULT, GAME_OVER }; 53GameState currentState = READY; 54 55String humanGesture = "", robotGesture = "", gameResult = ""; 56unsigned long gameStartTime = 0; 57int countdownNumber = 3; 58 59int humanWins = 0, robotWins = 0; 60 61void setGameLED(int r, int g, int b) { myCobot.setLEDRGB(r, g, b); } 62void setReadyLED() { setGameLED(0,0,0); } 63void setGameRunningLED() { setGameLED(0,0,255); } 64void setRobotWinLED() { setGameLED(0,255,0); } 65void setHumanWinLED() { setGameLED(255,0,0); } 66void setTieLED() { setGameLED(255,255,0); } 67 68// ===================== MOTION ===================== 69void moveToNeutral() { 70 myCobot.writeAngle(1, 0, SERVO_SPEED); delay(200); 71 myCobot.writeAngle(2, 0, SERVO_SPEED); delay(200); 72 myCobot.writeAngle(3, 0, SERVO_SPEED); delay(200); 73 myCobot.writeAngle(4, -90, SERVO_SPEED);delay(200); 74 myCobot.writeAngle(5, 0, SERVO_SPEED); delay(200); 75 myCobot.writeAngle(6, -45, SERVO_SPEED);delay(200); 76 myCobot.setGripperState(1, 25); 77} 78 79void moveToGamePosition() { myCobot.writeAngle(4, 0, SERVO_SPEED*1.1); delay(800); } 80 81void victoryRoutine() { myCobot.writeAngle(4, -50, SERVO_SPEED); delay(400); myCobot.writeAngle(4, 0, SERVO_SPEED); delay(300); } 82void defeatRoutine() { myCobot.writeAngle(4, 50, SERVO_SPEED); delay(400); myCobot.writeAngle(4, 0, SERVO_SPEED); delay(300); } 83void tieRoutine() { myCobot.writeAngle(5, 50, SERVO_SPEED); delay(250); myCobot.writeAngle(5,-50,SERVO_SPEED); delay(250); myCobot.writeAngle(5,0,SERVO_SPEED); delay(300); } 84 85void showPaper() { clickSound(); myCobot.setGripperState(0, 80); delay(1000); } 86void showRock() { clickSound(); myCobot.setGripperState(1, 40); delay(1000); } 87void showScissors() { 88 playTone(1000, 80); delay(120); 89 playTone(1200, 80); 90 myCobot.setGripperState(1, 80); delay(500); 91 myCobot.setGripperState(0, 80); delay(500); 92 myCobot.setGripperState(1, 80); delay(1000); 93} 94 95// ===================== DISPLAY ===================== 96void showReadyScreen() { 97 M5.Lcd.fillScreen(BLACK); 98 M5.Lcd.setTextColor(WHITE); 99 M5.Lcd.setTextSize(4); 100 M5.Lcd.setCursor(50, 10); M5.Lcd.print("ROCK"); 101 M5.Lcd.setCursor(170, 10); M5.Lcd.print("PAPER"); 102 M5.Lcd.setCursor(80, 60); M5.Lcd.println("SCISSORS"); 103 M5.Lcd.setCursor(110, 110); M5.Lcd.println("GAME"); 104 105 M5.Lcd.setTextSize(3); 106 // Your custom positions preserved 107 M5.Lcd.setCursor(30, 160); M5.Lcd.println("A: START"); 108 M5.Lcd.setCursor(30, 200); M5.Lcd.println("B: POSITION"); 109 M5.Lcd.setCursor(30, 240); M5.Lcd.println("C: RESULT"); 110} 111 112void showGameOverScreen() { 113 M5.Lcd.fillScreen(BLACK); 114 M5.Lcd.setTextColor(WHITE); 115 M5.Lcd.setTextSize(4); 116 M5.Lcd.setCursor(40, 40); M5.Lcd.println("Game over"); 117 M5.Lcd.setTextSize(3); 118 M5.Lcd.setCursor(30, 130); M5.Lcd.println("A: New Game"); 119 M5.Lcd.setCursor(30, 170); M5.Lcd.println("B: Reposition"); 120 M5.Lcd.setCursor(30, 210); M5.Lcd.println("C: Total Score"); 121} 122 123void showTotalResultScreen() { 124 M5.Lcd.fillRect(0, 0, 320, 120, RED); 125 M5.Lcd.setTextColor(BLACK); 126 M5.Lcd.setTextSize(4); 127 M5.Lcd.setCursor(40, 40); 128 M5.Lcd.printf("HUMAN: %d", humanWins); 129 130 M5.Lcd.fillRect(0, 120, 320, 120, GREEN); 131 M5.Lcd.setTextColor(BLACK); 132 M5.Lcd.setTextSize(4); 133 M5.Lcd.setCursor(40, 160); 134 M5.Lcd.printf("ROBOT: %d", robotWins); 135 136 delay(2500); 137 if (currentState == GAME_OVER) showGameOverScreen(); 138 else showReadyScreen(); 139} 140 141// ===================== GAME LOGIC ===================== 142void initializeGame() { 143 currentState = READY; 144 humanGesture = ""; robotGesture = ""; gameResult = ""; 145 setReadyLED(); 146 showReadyScreen(); 147} 148 149void startNewGame() { 150 currentState = COUNTDOWN; 151 countdownNumber = 3; 152 gameStartTime = millis(); 153 154 moveToGamePosition(); 155 setGameRunningLED(); 156 157 M5.Lcd.fillScreen(BLUE); 158 M5.Lcd.setTextColor(WHITE); 159 M5.Lcd.setTextSize(4); 160 M5.Lcd.setCursor(50, 100); 161 M5.Lcd.println("Waiting..."); 162 delay(600); 163 164 for (int i = 3; i > 0; i--) { 165 M5.Lcd.fillScreen(BLACK); 166 M5.Lcd.setTextColor(YELLOW); 167 M5.Lcd.setTextSize(10); 168 M5.Lcd.setCursor(140, 100); 169 M5.Lcd.println(i); 170 countdownBeep(i); 171 delay(650); 172 } 173 174 M5.Lcd.fillScreen(GREEN); 175 M5.Lcd.setTextColor(BLACK); 176 M5.Lcd.setTextSize(5); 177 M5.Lcd.setCursor(70, 100); 178 M5.Lcd.println("SHOOT!"); 179 shootSound(); 180 delay(700); 181 182 currentState = REVEAL; 183 M5.Lcd.fillScreen(BLUE); 184 M5.Lcd.setTextColor(WHITE); 185 M5.Lcd.setTextSize(4); 186 M5.Lcd.setCursor(35, 80); M5.Lcd.println("Waiting for"); 187 M5.Lcd.setCursor(75, 120); M5.Lcd.println("gesture"); 188} 189 190void generateRobotGesture() { 191 int choice = random(0, 3); 192 robotGesture = (choice == 0) ? "rock" : (choice == 1) ? "paper" : "scissors"; 193} 194 195void determineWinner() { 196 if (humanGesture == robotGesture) gameResult = "tie"; 197 else if ((humanGesture == "rock" && robotGesture == "scissors") || 198 (humanGesture == "paper" && robotGesture == "rock") || 199 (humanGesture == "scissors" && robotGesture == "paper")) gameResult = "human"; 200 else gameResult = "robot"; 201} 202 203void showResults() { 204 M5.Lcd.fillRect(0, 0, 320, 120, RED); 205 M5.Lcd.setTextColor(BLACK); M5.Lcd.setTextSize(4); 206 M5.Lcd.setCursor(50, 40); M5.Lcd.print("H: "); M5.Lcd.println(humanGesture); 207 208 M5.Lcd.fillRect(0, 120, 320, 120, GREEN); 209 M5.Lcd.setTextColor(BLACK); M5.Lcd.setTextSize(4); 210 M5.Lcd.setCursor(50, 160); M5.Lcd.print("R: "); M5.Lcd.println(robotGesture); 211 212 delay(600); 213 214 if (robotGesture == "rock") showRock(); 215 else if (robotGesture == "paper") showPaper(); 216 else showScissors(); 217 218 delay(400); 219 220 if (gameResult == "robot") { 221 robotWins++; 222 setRobotWinLED(); 223 M5.Lcd.fillScreen(GREEN); 224 M5.Lcd.setTextColor(BLACK); 225 M5.Lcd.setTextSize(5); 226 M5.Lcd.setCursor(80, 100); M5.Lcd.println("I WIN!"); 227 victorySound(); 228 victoryRoutine(); 229 } else if (gameResult == "human") { 230 humanWins++; 231 setHumanWinLED(); 232 M5.Lcd.fillScreen(RED); 233 M5.Lcd.setTextColor(WHITE); 234 M5.Lcd.setTextSize(5); 235 M5.Lcd.setCursor(50, 100); M5.Lcd.println("YOU WIN!"); 236 defeatSound(); 237 defeatRoutine(); 238 } else { 239 setTieLED(); 240 M5.Lcd.fillScreen(YELLOW); 241 M5.Lcd.setTextColor(BLACK); 242 M5.Lcd.setTextSize(5); 243 M5.Lcd.setCursor(90, 100); M5.Lcd.println("TIE!"); 244 tieSound(); 245 tieRoutine(); 246 } 247 248 delay(1600); 249 moveToNeutral(); 250 showGameOverScreen(); 251 currentState = GAME_OVER; 252 setReadyLED(); 253} 254 255// ===================== COMMAND & MAIN LOOP ===================== 256void processHumanGesture(String gesture) { 257 if (currentState != REVEAL) return; 258 humanGesture = gesture; 259 generateRobotGesture(); 260 determineWinner(); 261 showResults(); 262} 263 264void processCommand(String command) { 265 command.trim(); command.toLowerCase(); 266 if (command.startsWith("human:")) { 267 String gesture = command.substring(6); 268 if (gesture == "rock" || gesture == "paper" || gesture == "scissors") { 269 selectSound(); 270 processHumanGesture(gesture); 271 } 272 } else if (command == "reset") { 273 clickSound(); 274 initializeGame(); 275 } 276} 277 278void setup() { 279 M5.begin(); 280 Serial.begin(115200); 281 myCobot.setup(); 282 myCobot.powerOn(); 283 initSpeaker(); 284 for (int i = 0; i < 3; ++i) { playTone(900 + i*150, 90); delay(90); } 285 randomSeed(analogRead(0)); 286 initializeGame(); 287 } 288 289 290void loop() { 291 M5.update(); 292 293 if (M5.BtnB.wasPressed()) { 294 clickSound(); 295 moveToNeutral(); 296 setReadyLED(); 297 showReadyScreen(); 298 currentState = READY; 299 } 300 301 if (M5.BtnA.wasPressed()) { 302 selectSound(); 303 if (currentState == READY || currentState == GAME_OVER) 304 startNewGame(); 305 } 306 307 if (M5.BtnC.wasPressed()) { 308 if (currentState == READY || currentState == GAME_OVER) { 309 clickSound(); 310 showTotalResultScreen(); 311 } 312 } 313 314 if (Serial.available() > 0) { 315 String command = Serial.readStringUntil('\n'); 316 processCommand(command); 317 } 318 319 delay(100); 320}
Downloadable files
python code
...
MediaPIPE_Code (Python).py
Documentation
libs
...
Libraries.zip
all codes
. ..
all Codes.zip
Comments
Only logged in users can leave comments