http://currentmillis.com/

博客主要围绕MySQL中毫秒转时间展开,聚焦于信息技术里数据库操作方面,为相关人员提供了在MySQL环境下进行毫秒到时间转换的内容。
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 20, 4); // 20列4行LCD // 引脚定义 const int GATE1_PIN = 2; const int GATE2_PIN = 3; const int BUZZER_PIN = 8; // 新增蜂鸣器引脚 // 实验参数 const float WIDTH = 0.01; // 挡光片宽度(米) float gateDistance = 0.30; // 光电门间距(米) // 时间记录变量 volatile unsigned long gate1Start = 0; volatile unsigned long gate1End = 0; volatile unsigned long gate2Start = 0; volatile unsigned long gate2End = 0; // 状态标志 volatile bool gate1Blocked = false; volatile bool gate2Blocked = false; bool experimentComplete = false; // 去抖动相关变量 const unsigned long DEBOUNCE_DELAY = 100; // 消抖时间(微秒) volatile unsigned long lastGate1Time = 0; volatile unsigned long lastGate2Time = 0; // 蜂鸣器控制变量 unsigned long lastBeepTime = 0; int beepState = 0; // 0=空闲, 1=触发提示, 2=完成提示, 3=错误提示 void setup() { Serial.begin(115200); // 初始化LCD lcd.init(); lcd.backlight(); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Physics Experiment"); lcd.setCursor(0, 1); lcd.print("Photogate System"); lcd.setCursor(0, 2); lcd.print("Waiting for trigger"); // 初始化引脚模式 pinMode(GATE1_PIN, INPUT_PULLUP); pinMode(GATE2_PIN, INPUT_PULLUP); pinMode(BUZZER_PIN, OUTPUT); // 设置蜂鸣器为输出模式 // 配置中断 attachInterrupt(digitalPinToInterrupt(GATE1_PIN), gate1ISR, CHANGE); attachInterrupt(digitalPinToInterrupt(GATE2_PIN), gate2ISR, CHANGE); Serial.println("实验系统就绪..."); Serial.println("--------------------------------------"); } void loop() { handleBuzzer(); // 处理蜂鸣器状态 if (experimentComplete) { calculateAndPrintResults(); resetExperiment(); delay(10000); // 结果展示时间 // 重置显示 // lcd.clear(); // lcd.setCursor(0, 0); //lcd.print("Ready for next"); //lcd.setCursor(0, 1); //lcd.print("experiment..."); } } // 蜂鸣器控制函数(非阻塞方式) void handleBuzzer() { unsigned long currentMillis = millis(); switch (beepState) { case 0: // 空闲状态 digitalWrite(BUZZER_PIN, LOW); break; case 1: // 光电门触发提示(短鸣200ms) if (currentMillis - lastBeepTime > 200) { digitalWrite(BUZZER_PIN, LOW); beepState = 0; } break; case 2: // 实验完成提示(两次短鸣) if (currentMillis - lastBeepTime < 200) { digitalWrite(BUZZER_PIN, HIGH); } else if (currentMillis - lastBeepTime < 400) { digitalWrite(BUZZER_PIN, LOW); } else if (currentMillis - lastBeepTime < 600) { digitalWrite(BUZZER_PIN, HIGH); } else { digitalWrite(BUZZER_PIN, LOW); beepState = 0; } break; case 3: // 错误提示(长鸣1秒) if (currentMillis - lastBeepTime < 1000) { digitalWrite(BUZZER_PIN, HIGH); } else { digitalWrite(BUZZER_PIN, LOW); beepState = 0; } break; } } // 触发蜂鸣器 void triggerBeep(int type) { beepState = type; lastBeepTime = millis(); digitalWrite(BUZZER_PIN, HIGH); // 立即开始发声 } // 光电门1中断服务函数 void gate1ISR() { // 软件消抖处理 if (micros() - lastGate1Time < DEBOUNCE_DELAY) return; lastGate1Time = micros(); if (digitalRead(GATE1_PIN) == LOW) { // 挡光开始 (低电平触发) gate1Start = micros(); gate1Blocked = true; // 触发蜂鸣器(短鸣提示) triggerBeep(1); } else { // 挡光结束 if (gate1Blocked) { gate1End = micros(); gate1Blocked = false; // 更新LCD显示 lcd.setCursor(0, 3); lcd.print("G1:"); lcd.print(gate1End - gate1Start); lcd.print("us "); } } } // 光电门2中断服务函数 void gate2ISR() { // 软件消抖处理 if (micros() - lastGate2Time < DEBOUNCE_DELAY) return; lastGate2Time = micros(); if (digitalRead(GATE2_PIN) == LOW) { // 挡光开始 gate2Start = micros(); gate2Blocked = true; // 触发蜂鸣器(短鸣提示) triggerBeep(1); } else { // 挡光结束 if (gate2Blocked) { gate2End = micros(); gate2Blocked = false; experimentComplete = true; // 设置实验完成标志 // 更新LCD显示 lcd.setCursor(10, 3); lcd.print("G2:"); lcd.print(gate2End - gate2Start); lcd.print("us "); // 触发完成提示音(稍后发出) triggerBeep(2); } } } // 计算并打印实验结果 void calculateAndPrintResults() { if (gate1Start == 0 || gate1End == 0 || gate2Start == 0 || gate2End == 0) { Serial.println("错误: 数据不完整!"); lcd.clear(); lcd.print("Error: Incomplete"); lcd.setCursor(0, 1); lcd.print("data!"); // 触发错误提示音 triggerBeep(3); return; } // 计算挡光时间 (微秒) unsigned long time1 = gate1End - gate1Start; unsigned long time2 = gate2End - gate2Start; // 计算通过光电门的时间点 (中心时刻) unsigned long midTime1 = gate1Start + time1/2; unsigned long midTime2 = gate2Start + time2/2; // 计算时间间隔 (秒) float timeInterval = (midTime2 - midTime1) / 1000000.0; // 计算瞬时速度 (米/秒) float velocity1 = WIDTH / (time1 / 1000000.0); float velocity2 = WIDTH / (time2 / 1000000.0); // 计算加速度 (米/秒²) float acceleration = (velocity2 - velocity1) / timeInterval; // 打印实验结果到串口 Serial.println("===== 实验数据 ====="); Serial.print("光电门1挡光时间: "); Serial.print(time1); Serial.println(" μs"); Serial.print("光电门2挡光时间: "); Serial.print(time2); Serial.println(" μs"); Serial.print("通过光电门1速度: "); Serial.print(velocity1, 4); Serial.println(" m/s"); Serial.print("通过光电门2速度: "); Serial.print(velocity2, 4); Serial.println(" m/s"); Serial.print("加速度: "); Serial.print(acceleration, 4); Serial.println(" m/s²"); Serial.println("--------------------------------------"); // 显示结果到LCD lcd.clear(); lcd.setCursor(0, 0); lcd.print("V1: "); lcd.print(velocity1, 3); lcd.print(" m/s"); lcd.setCursor(0, 1); lcd.print("V2: "); lcd.print(velocity2, 3); lcd.print(" m/s"); lcd.setCursor(0, 2); lcd.print("Acc: "); lcd.print(acceleration, 3); lcd.print(" m/s2"); lcd.setCursor(0, 3); lcd.print("dt: "); lcd.print(timeInterval * 1000, 2); lcd.print(" ms"); } // 重置实验状态 void resetExperiment() { gate1Blocked = false; gate2Blocked = false; experimentComplete = false; gate1Start = 0; gate1End = 0; gate2Start = 0; gate2End = 0; } 我现在使用eeprom存储数据请你在此代码的基础上添加
11-24
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <DHT.h> // OLED显示屏配置 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // DHT11传感器配置 #define DHT_PIN 2 #define DHT_TYPE DHT11 DHT dht(DHT_PIN, DHT_TYPE); // 变量声明 float temperature = 0; float humidity = 0; unsigned long previousMillis = 0; const long interval = 2000; // 更新间隔(毫秒) void setup() { // 初始化串口通信 Serial.begin(9600); // 初始化OLED显示屏 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306分配失败")); for(;;); // 停止执行 } // 初始化DHT传感器 dht.begin(); // 清屏并显示欢迎信息 display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0,0); display.println("温湿度监测系统"); display.println("初始化中..."); display.display(); delay(2000); } void loop() { unsigned long currentMillis = millis(); // 每2秒更新一次数据 if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // 读取传感器数据 readSensorData(); // 更新显示 updateDisplay(); } } void readSensorData() { // 读取温度湿度 temperature = dht.readTemperature(); humidity = dht.readHumidity(); // 检查读取是否成功 if (isnan(temperature) || isnan(humidity)) { Serial.println("读取DHT传感器失败!"); return; } // 串口输出数据 Serial.print("温度: "); Serial.print(temperature); Serial.print(" °C, 湿度: "); Serial.print(humidity); Serial.println(" %"); } void updateDisplay() { display.clearDisplay(); // 显示标题 display.setTextSize(1); display.setCursor(0,0); display.println("环境监测系统"); display.drawLine(0, 10, 128, 10, SSD1306_WHITE); // 显示温度 display.setCursor(0, 15); display.print("温度: "); display.setTextSize(2); display.setCursor(0, 25); display.print(temperature, 1); display.print(" "); display.setTextSize(1); display.cp437(true); display.write(167); // 度符号 display.setTextSize(2); display.print("C"); // 显示湿度 display.setTextSize(1); display.setCursor(0, 45); display.print("湿度: "); display.setTextSize(2); display.setCursor(0, 55); display.print(humidity, 0); display.print(" %"); // 显示状态指示 display.setTextSize(1); display.setCursor(90, 55); if (temperature > 30) { display.print("热"); } else if (temperature < 15) { display.print("冷"); } else { display.print("舒适"); } display.display(); }
10-18
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // -------------------------- 硬件引脚定义 -------------------------- #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_RESET -1 #define IN1 11 #define IN2 10 #define IN3 6 #define IN4 5 #define BUZZER_PIN 3 #define OBSTACLE_FRONT A4 #define OBSTACLE_LEFT A3 #define OBSTACLE_RIGHT A2 #define VOLTAGE_PIN A0 #define CURRENT_PIN A1 #define LED_PIN 13 // -------------------------- 全局变量定义 -------------------------- Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); int voltageAdc = 0; int currentAdc = 0; const float ADC_REF = 5.0; const int ADC_MAX = 1023; const float VOLT_DIV = 3.0; const float ALERT_VOLT = 7.0; int toneFreq[] = {196, 220, 247, 262, 294, 330, 349, 392, 440, 494, 523}; int birthdayNotes[] = {3,3,4,3,6,5, 3,3,4,3,7,6, 3,3,10,8,6,5,4, 9,9,8,6,7,6}; int birthdayDurations[] = {8,8,4,4,4,4, 8,8,4,4,4,4, 8,8,4,4,4,4,4, 8,8,4,4,4,4}; int counter = 0; // 非阻塞计时变量 unsigned long songTimer = 0; int songIndex = 0; unsigned long noteEndTime = 0; unsigned long alertTimer = 0; bool isAlertOn = false; // -------------------------- 函数声明 -------------------------- void playBirthdaySongNonBlock(); void readAndCalculatePower(float *volt, float *curr, float *power); void displayInfo(float volt, float curr, float power); void voltageAlertNonBlock(); void setup() { // 初始化OLED(I2C速率回落至200kHz,平衡速度与稳定性) Wire.setClock(200000); if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { for(;;); } display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.setTextSize(1); display.setTextWrap(false); // 初始化硬件引脚 pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); pinMode(IN3, OUTPUT); pinMode(IN4, OUTPUT); digitalWrite(LED_PIN, LOW); } void loop() { unsigned long currentMillis = millis(); // 1. 读取电压、电流(每150ms一次,降低数据采集频率) static unsigned long powerReadTimer = 0; float voltage = 0, current = 0, power = 0; if (currentMillis - powerReadTimer >= 50) { readAndCalculatePower(&voltage, &current, &power); powerReadTimer = currentMillis; // 2. 同步更新显示(与数据采集绑定,每150ms刷新1次,避免过快闪烁) displayInfo(voltage, current, power); counter++; } // 3. 电压报警逻辑(非阻塞,报警间隔微调至1.8秒,避免过频) if (voltage < ALERT_VOLT) { voltageAlertNonBlock(); } else { // 4. 非阻塞播放生日歌(音符间隔增加至80ms,歌曲节奏更舒缓) playBirthdaySongNonBlock(); } } // -------------------------- 函数实现 -------------------------- // 非阻塞播放生日歌(放缓节奏) void playBirthdaySongNonBlock() { unsigned long currentMillis = millis(); int noteCount = sizeof(birthdayNotes)/sizeof(birthdayNotes[0]); // 整首歌播放完后,暂停1.5秒再重置(延长间隔) if (currentMillis - songTimer >= 1500 && songIndex == noteCount) { songIndex = 0; songTimer = currentMillis; noTone(BUZZER_PIN); return; } if (currentMillis >= noteEndTime && songIndex < noteCount) { int noteIdx = birthdayNotes[songIndex]; int duration = 1000 / (birthdayDurations[songIndex]/2); if (noteIdx != 0) { tone(BUZZER_PIN, toneFreq[noteIdx]); } else { noTone(BUZZER_PIN); } noteEndTime = currentMillis + duration; songIndex++; } else if (currentMillis >= noteEndTime && songIndex < noteCount) { noTone(BUZZER_PIN); delay(80); // 增加音符间隔,放缓歌曲节奏 } } // 读取电压电流并计算功率 void readAndCalculatePower(float *volt, float *curr, float *power) { voltageAdc = analogRead(VOLTAGE_PIN); float adcVolt = (voltageAdc * ADC_REF) / ADC_MAX; *volt = adcVolt * VOLT_DIV; currentAdc = analogRead(CURRENT_PIN); float adcCurrVolt = (currentAdc * ADC_REF) / ADC_MAX; *curr = ((adcCurrVolt - 2.5) / 0.5) * 1000; *power = *volt * (*curr / 1000.0); } // OLED显示逻辑(保持简洁,避免额外开销) void displayInfo(float volt, float curr, float power) { display.clearDisplay(); // 显示标题和计数器 display.setCursor(10, 0); display.print("20"); // 显示核心数据 display.setTextSize(2); display.setCursor(0, 12); display.print("U:"); display.print(volt, 1); display.print("V"); display.setCursor(0, 30); display.print("I:"); display.print(curr, 0); display.print("mA"); display.setCursor(0, 50); display.print("P:"); display.print(power, 2); display.print("W"); display.display(); } // 非阻塞电压报警(放缓报警频率) void voltageAlertNonBlock() { unsigned long currentMillis = millis(); // 报警间隔从1.5秒延长至1.8秒,避免频繁切换 if (currentMillis - alertTimer >= 1800) { alertTimer = currentMillis; isAlertOn = !isAlertOn; } if (isAlertOn) { tone(BUZZER_PIN, 1000); digitalWrite(LED_PIN, HIGH); } else { noTone(BUZZER_PIN); digitalWrite(LED_PIN, LOW); } } #include<Arduino.h> #include <SoftwareSerial.h> // 一、蓝牙模块配置(Nano推荐引脚,烧录时需断开RX/TX接线) #define BT_RX_PIN 0 // Arduino接收 → 蓝牙模块TX #define BT_TX_PIN 1 // Arduino发送 → 蓝牙模块RX SoftwareSerial bluetooth(BT_RX_PIN, BT_TX_PIN); char btCmd; // 存储蓝牙接收的指令 bool motorStatus = false; // 电机状态:false=关闭,true=开启 // 二、电机引脚配置(左D10/D11,右D5/D6,按你的需求定义) #define LEFT_IN1 10 // 左电机控制脚1 #define LEFT_IN2 11 // 左电机控制脚2 #define RIGHT_IN3 5 // 右电机控制脚1 #define RIGHT_IN4 6 // 右电机控制脚2 void setup() { // 1. 初始化串口与蓝牙(HC-05默认9600波特率,其他模块需修改) Serial.begin(9600); while (!Serial); // 等待电脑串口就绪 bluetooth.begin(115200); Serial.println("蓝牙已启动,指令说明:"); Serial.println("F=前进,B=后退,L=左转,R=右转,U=电机开,O=电机关,S=停止"); // 2. 配置电机引脚为输出模式,初始状态电机关闭 pinMode(LEFT_IN1, OUTPUT); pinMode(LEFT_IN2, OUTPUT); pinMode(RIGHT_IN3, OUTPUT); pinMode(RIGHT_IN4, OUTPUT); stopCar(); // 初始化小车停止 } void loop() { // 读取蓝牙指令并执行对应操作 if (bluetooth.available() > 0) { btCmd = bluetooth.read(); Serial.print("收到指令:"); Serial.println(btCmd); controlCar(btCmd); // 执行指令对应的小车动作 } } // 三、小车核心控制逻辑(指令→动作映射) void controlCar(char cmd) { // 只有电机开启(motorStatus=true)时,才能执行运动指令;关闭时仅响应U/O/S switch(cmd) { case 'U': // 电机开启(默认进入前进状态) motorStatus = true; Serial.println("电机已开启,当前状态:前进"); digitalWrite(LEFT_IN1, HIGH); digitalWrite(LEFT_IN2, LOW); digitalWrite(RIGHT_IN3, LOW); digitalWrite(RIGHT_IN4, HIGH); break; case 'O': // 电机关闭(所有电机断电) motorStatus = false; stopCar(); Serial.println("电机已关闭"); break; case 'S': // 停止(电机保持开启状态,但当前动作停止) stopCar(); Serial.println("小车停止"); break; case 'F': // 前进(需电机已开启) if (motorStatus) { Serial.println("小车前进"); digitalWrite(LEFT_IN1, HIGH); digitalWrite(LEFT_IN2, LOW); digitalWrite(RIGHT_IN3, LOW); digitalWrite(RIGHT_IN4, HIGH); } else { Serial.println("电机未开启,请先发送指令U"); } break; case 'B': // 后退(需电机已开启) if (motorStatus) { Serial.println("小车后退"); digitalWrite(LEFT_IN1, LOW); digitalWrite(LEFT_IN2, HIGH); digitalWrite(RIGHT_IN3, HIGH); digitalWrite(RIGHT_IN4, LOW); } else { Serial.println("电机未开启,请先发送指令U"); } break; case 'L': // 左转(需电机已开启:右电机转,左电机停) if (motorStatus) { Serial.println("小车左转"); digitalWrite(LEFT_IN1, LOW); digitalWrite(LEFT_IN2, LOW); digitalWrite(RIGHT_IN3, LOW); digitalWrite(RIGHT_IN4, HIGH); } else { Serial.println("电机未开启,请先发送指令U"); } break; case 'R': // 右转(需电机已开启:左电机转,右电机停) if (motorStatus) { Serial.println("小车右转"); digitalWrite(LEFT_IN1, HIGH); digitalWrite(LEFT_IN2, LOW); digitalWrite(RIGHT_IN3, LOW); digitalWrite(RIGHT_IN4, LOW); } else { Serial.println("电机未开启,请先发送指令U"); } break; default: // 未知指令 Serial.println("指令错误!仅支持F/B/L/R/U/O/S"); break; } } // 四、电机停止函数(所有控制脚置低,电机断电) void stopCar() { digitalWrite(LEFT_IN1, LOW); digitalWrite(LEFT_IN2, LOW); digitalWrite(RIGHT_IN3, LOW); digitalWrite(RIGHT_IN4, LOW); } 根据这两份代码,生成一份代码,要求可以在小车运动的同时可以播放音乐,电源低于7v是可以预警,小车上的显示屏可以显示电压电流功率。且手机上的蓝牙遥控界面中text会显示显示屏上的电压电流功率
10-21
本项目采用C++编程语言结合ROS框架构建了完整的双机械臂控制系统,实现了Gazebo仿真环境下的协同运动模拟,并完成了两台实体UR10工业机器人的联动控制。该毕业设计在答辩环节获得98分的优异成绩,所有程序代码均通过系统性调试验证,保证可直接部署运行。 系统架构包含三个核心模块:基于ROS通信架构的双臂协调控制器、Gazebo物理引擎下的动力学仿真环境、以及真实UR10机器人的硬件接口层。在仿真验证阶段,开发了双臂碰撞检测算法和轨迹规划模块,通过ROS控制包实现了末端执行器的同步轨迹跟踪。硬件集成方面,建立了基于TCP/IP协议的实时通信链路,解决了双机数据同步和运动指令分发等关键技术问题。 本资源适用于自动化、机械电子、人工智能等专业方向的课程实践,可作为高年级课程设计、毕业课题的重要参考案例。系统采用模块化设计理念,控制核心与硬件接口分离架构便于功能扩展,具备工程实践能力的学习者可在现有框架基础上进行二次开发,例如集成视觉感知模块或优化运动规划算法。 项目文档详细记录了环境配置流程、参数调试方法和实验验证数据,特别说明了双机协同作业时的时序同步解决方案。所有功能模块均提供完整的API接口说明,便于使用者快速理解系统架构并进行定制化修改。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值