瀏覽代碼

Added actual firmware

Toby Chui 10 月之前
父節點
當前提交
e361da49e7

+ 70 - 0
firmware/cute_useless_robot/cute_useless_robot.ino

@@ -0,0 +1,70 @@
+/*
+
+    Cute Useless Robot (´・ω・`)
+
+    Developed by tobychui
+    Original design by Kairoshi
+
+*/
+
+/* Libraries */
+#include <MD_MAX72xx.h>
+#include <SPI.h>
+#include <Servo.h> //Require ESP32Servo, not the Arduino build in Servo.h
+
+/* Pins Definations */
+#define STP_DATA_PIN 4    // Stepper Shift Register DS
+#define STP_CLOCK_PIN 16  // Stepper Shift Register SH_CP
+#define STP_LATCH_PIN 17  // Stepper Shift Register ST_CP
+
+#define SERVO_SWITCH 27 //Servo to push the switch
+#define SERVO_COVER 14  //Servo to push the cover
+
+#define DP_CLK_PIN   32 //Display CLK
+#define DP_DATA_PIN  33 //Display DIN
+#define DP_CS_PIN    25 //Display CS
+/* Display settings generated by trial and error. Don't touch these */
+#define HARDWARE_TYPE MD_MAX72XX::DR1CR0RR0_HW
+#define MAX_DEVICES 8
+
+/* Hardware Type Definations */
+Servo servoSwitchPusher;
+Servo servoCoverPusher;
+MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DP_DATA_PIN, DP_CLK_PIN, DP_CS_PIN, MAX_DEVICES);
+
+void setup() {
+  Serial.begin(115200);
+  
+  /* Stepper IO */
+  pinMode(STP_DATA_PIN, OUTPUT);
+  pinMode(STP_CLOCK_PIN, OUTPUT);
+  pinMode(STP_LATCH_PIN, OUTPUT);
+  /* Servo IO */
+  servoSwitchPusher.attach(SERVO_SWITCH);
+  servoCoverPusher.attach(SERVO_COVER);
+  /* Display Module */
+  mx.begin();
+  setDisplayBrightness(0x4);
+  renderFrame();
+  delay(5000);
+}
+
+void loop() {
+  //Stepper test
+  forward(50);
+  delay(3000);
+  backward(50);
+  delay(3000);
+  rotateAntiClockwise(100);
+  delay(3000);
+  rotateClockwise(100);
+  delay(3000);
+  //Servo test
+  servoCoverPusher.write(90);
+  delay(1000);
+  servoSwitchPusher.write(180);
+  delay(1000);
+  servoCoverPusher.write(0);
+  servoSwitchPusher.write(0);
+  delay(3000);
+}

+ 75 - 0
firmware/cute_useless_robot/display.ino

@@ -0,0 +1,75 @@
+/* 
+  LED Matrix Display Driver 
+  
+  Library doc
+  https://majicdesigns.github.io/MD_MAX72XX/class_m_d___m_a_x72_x_x.html
+*/
+
+//frame buffer, 32x16px
+//each LED is 1 bit
+unsigned char frame_buffer[] = {
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x44,
+  0x44, 0x00, 0x00, 0x22,
+  0x89, 0x80, 0x01, 0x91,
+  0x92, 0x40, 0x02, 0x49,
+  0x82, 0x40, 0x02, 0x41,
+  0x81, 0x80, 0x01, 0x81,
+  0x80, 0x04, 0x40, 0x01,
+  0x80, 0x09, 0x20, 0x01,
+  0x87, 0x89, 0x21, 0xe1,
+  0x40, 0x06, 0xc0, 0x02,
+  0x27, 0x80, 0x01, 0xe4,
+  0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+
+//Helper function to reverse a byte in bits
+//e.g. 11011101 -> 10111011
+byte fByte(byte c) {
+  char r = 0;
+  for (byte i = 0; i < 8; i++) {
+    r <<= 1;
+    r |= c & 1;
+    c >>= 1;
+  } return r;
+}
+
+/*
+ * renderFrame render the frame buffer to display 
+ * 
+ * The display is an upside down two split LED grid matrix display
+ * the render sequence (when viewed from front) is as follows 
+ * and each matrix module is upside down (row 0 on bottom)
+ * [8][7][6][5]
+ * [4][3][2][1]
+ * 
+ */
+void renderFrame() {
+  //Top half of the display
+  int fsize = sizeof(frame_buffer);
+  for (int i = 0; i < fsize / 2; i += 4) {
+    for (int d = 0; d <= 3; d++) {
+      //For each of the driver, from 0 to 3
+      byte rowData = frame_buffer[i + d];
+      mx.setRow(d, d, 7 - int(i / 4), fByte(rowData));
+    }
+  }
+  //Bottom half of the display
+  for (int i = fsize / 2; i < fsize; i += 4) {
+    for (int d = 4; d <= 7; d++) {
+      //For each of the driver, from 4 to 7
+      byte rowData = frame_buffer[i + (d - 4)];
+      mx.setRow(d, d, 7 - (int(i / 4) - 8), fByte(rowData));
+    }
+  }
+}
+
+//Set display brightness, from 0x0 to 0xF
+void setDisplayBrightness(byte brightness){
+  for(int i =0; i<MAX_DEVICES; i++){
+    mx.control(i,MD_MAX72XX::INTENSITY, brightness);
+  }
+}

+ 66 - 0
firmware/cute_useless_robot/stepper.ino

@@ -0,0 +1,66 @@
+/* Stepper Drivers Functions */
+
+//writeStep write the step given the byte representation of a step on both stepper
+//e.g. writeStep(0b00110011); 
+void writeStep(byte stepByte) {
+  shiftOut(STP_DATA_PIN, STP_CLOCK_PIN, MSBFIRST, stepByte);
+  digitalWrite(STP_LATCH_PIN, HIGH);
+  digitalWrite(STP_LATCH_PIN, LOW);
+  delayMicroseconds(840); //780 - 800 ms minimum, recommend 840 to 860ms
+}
+
+//Move the robot forward by 8 * rev micro steps 
+void forward(int rev) {
+  for (int i = 0; i < rev; i++) {
+    writeStep(0b00010001);
+    writeStep(0b00110011);
+    writeStep(0b00100010);
+    writeStep(0b01100110);
+    writeStep(0b01000100);
+    writeStep(0b11001100);
+    writeStep(0b10001000);
+    writeStep(0b10011001);
+  }
+}
+
+//Move the robot backward by 8 * rev micro steps 
+void backward(int rev) {
+  for (int i = 0; i < rev; i++) {
+    writeStep(0b10011001);
+    writeStep(0b10001000);
+    writeStep(0b11001100);
+    writeStep(0b01000100);
+    writeStep(0b01100110);
+    writeStep(0b00100010);
+    writeStep(0b00110011);
+    writeStep(0b00010001);
+  }
+}
+
+//Differential offset the robot wheels by +- 8 * rev micro steps, anti-clockwise
+void rotateAntiClockwise(int rev) {
+  for (int i = 0; i < rev; i++) {
+    writeStep(0b00011001);
+    writeStep(0b00111000);
+    writeStep(0b00101100);
+    writeStep(0b01100100);
+    writeStep(0b01000110);
+    writeStep(0b11000010);
+    writeStep(0b10000011);
+    writeStep(0b10010001);
+  }
+}
+
+//Differential offset the robot wheels by +- 8 * rev micro steps, clockwise
+void rotateClockwise(int rev) {
+  for (int i = 0; i < rev; i++) {
+    writeStep(0b10010001);
+    writeStep(0b10000011);
+    writeStep(0b11000010);
+    writeStep(0b01000110);
+    writeStep(0b01100100);
+    writeStep(0b00101100);
+    writeStep(0b00111000);
+    writeStep(0b00011001);
+  }
+}