这次主要是回复Merlin-1D文章:939753
这次试车是我和Merlin同步设计的发动机,并进行试车,本次的采集卡主要是由我设计的,下面先看几张图片
这会儿嘉立创打不开了,就暂时不展示原理图了
这次的采集卡主控是nano上面同种328p的芯片,并采用了nrf作为数据传输,传感器的采集芯片是hx711芯片,采集版在发送数据的同时并将数据同步采集到SD卡中,但是我的发动机在点火之后,后期处理数据的时候发现数据波动太小了,连着把试车台都推动了,结果采集的数据只有21牛左右,具体的试车视频且看我朋友的那篇文章,推力是明显很大的,工作时间1~2s
下面是本次基于arduino ide编写的程序代码:
#include <SD.h> #include <HX711_ADC.h> #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #if defined(ESP8266)|| defined(ESP32) || defined(AVR) #include <EEPROM.h> #endif RF24 radio(6, 7); // CE, CSN引脚 File file; const byte address[6] = "0000"; const byte address2[6] = "Space.ST"; const int HX711_dout = 5; //接HX711 dout const int HX711_sck = 4; //接 HX711 sck HX711_ADC LoadCell(HX711_dout, HX711_sck); const int calVal_calVal_eepromAdress = 0; float a = 0; float i; int time = 0; int period = 1000; unsigned long timenow = 1000; unsigned long time2 = 0; void setup() { Serial.begin(115200); pinMode(3, INPUT_PULLUP); //设置复位按键 pinMode(8, OUTPUT); //设置蜂鸣器输出 pinMode(2, INPUT_PULLUP); if (!radio.begin()) { Serial.println("NRF初始化失败"); while (1) { digitalWrite(8, 1); delay(500); digitalWrite(8, 0); delay(500); } } if (!SD.begin()) { Serial.println("SD初始化失败"); while (1) { digitalWrite(8, 1); delay(500); digitalWrite(8, 0); delay(500); } } radio.setPALevel(RF24_PA_MIN); // 设置为最大发射功率 Serial.println("准备..."); float calibrationValue; calibrationValue = 30.61; //校准值根据实际情况进行修改 #if defined(ESP8266) || defined(ESP32) //EEPROM.begin(512); // uncomment this if you use ESP8266 and want to fetch this value from eeprom #endif //EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch this value from eeprom LoadCell.begin(); //LoadCell.setReverseOutput(); unsigned long stabilizingtime = 2000; // tare preciscion can be improved by adding a few seconds of stabilizing time boolean _tare = true; //set this to false if you don't want tare to be performed in the next step LoadCell.start(stabilizingtime, _tare); if (LoadCell.getTareTimeoutFlag()) { Serial.println("Timeout, check MCU>HX711 wiring and pin designations"); } else { LoadCell.setCalFactor(calibrationValue); // set calibration factor (float) Serial.println("Startup is complete"); } while (!LoadCell.update()); Serial.print("Calibration value: "); Serial.println(LoadCell.getCalFactor()); Serial.print("HX711 measured conversion time ms: "); Serial.println(LoadCell.getConversionTime()); Serial.print("HX711 measured sampling rate HZ: "); Serial.println(LoadCell.getSPS()); Serial.print("HX711 measured settlingtime ms: "); Serial.println(LoadCell.getSettlingTime()); Serial.println("Note that the settling time may increase significantly if you use delay() in your sketch!"); if (LoadCell.getSPS() < 7) { Serial.println("!!Sampling rate is lower than specification, check MCU>HX711 wiring and pin designations"); } else if (LoadCell.getSPS() > 100) { Serial.println("!!Sampling rate is higher than specification, check MCU>HX711 wiring and pin designations"); } file = SD.open("test.txt", FILE_WRITE); if (file) { file.println(" "); file.println(" "); file.println("以上数据作废 "); file.println("开始记录新数据:"); file.close(); } } void loop() { unsigned long timenow2 = millis(); static boolean newDataReady = 0; const int serialPrintInterval = 500; //increase value to slow down serial print activity // check for new data/start next conversion: if (LoadCell.update()) newDataReady = true; if (newDataReady) { i = LoadCell.getData(); } if (digitalRead(2) == 1) { if (timenow2 - time2 >= timenow) { time2 = timenow2; time++; } file = SD.open("test.txt", FILE_WRITE); file.print(i / 1000 * 9.8); //单位转换N file.print(" "); file.print(time); file.println("s"); file.close(); Serial.print(i); radio.openWritingPipe(address); radio.write(&i, sizeof(i)); Serial.print("g"); Serial.print(" "); Serial.print(i / 1000 * 9.8); Serial.print("N"); radio.openWritingPipe(address2); radio.write(&time, sizeof(time)); Serial.print(" "); Serial.print(time); Serial.println("s"); } else { time = 0; LoadCell.tareNoDelay(); } if (digitalRead(3) == 0) { LoadCell.tareNoDelay(); digitalWrite(8, 1); delay(500); digitalWrite(8, 0); time = 0; file = SD.open("test.txt", FILE_WRITE); if (file) { file.println(" "); file.println(" "); file.println("以上数据作废 "); file.println("开始记录新数据:"); file.close(); } } }
以上是发送端的代码
#include <SPI.h> #include <nRF24L01.h> #include <RF24.h> #include <Wire.h> #include <Adafruit_SSD1306.h> static const unsigned char PROGMEM sh[]{ 0x04, 0x00, 0xFF, 0xE0, 0x80, 0x20, 0x12, 0x00, 0x0A, 0x00, 0x22, 0x00, 0x12, 0x00, 0xFF, 0xE0, 0x04, 0x00, 0x09, 0x80, 0x30, 0x40, 0xC0, 0x20, /*"实",0*/ }; static const unsigned char PROGMEM shi[]{ 0x00, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x97, 0xE0, 0x90, 0x40, 0xF0, 0x40, 0x92, 0x40, 0x91, 0x40, 0x91, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x01, 0xC0, /*"时",1*/ }; static const unsigned char PROGMEM zui[]{ 0x3F, 0x80, 0x20, 0x80, 0x3F, 0x80, 0x20, 0x80, 0xFF, 0xE0, 0x48, 0x00, 0x7B, 0xC0, 0x49, 0x40, 0x79, 0x40, 0x4C, 0x80, 0xF9, 0x40, 0x0A, 0x20, /*"最",0*/ }; static const unsigned char PROGMEM da[]{ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0xFF, 0xE0, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x11, 0x00, 0x11, 0x00, 0x20, 0x80, 0xC0, 0x60, /*"大",1*/ }; static const unsigned char PROGMEM shi2[]{ 0x00, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x97, 0xE0, 0x90, 0x40, 0xF0, 0x40, 0x92, 0x40, 0x91, 0x40, 0x91, 0x40, 0xF0, 0x40, 0x90, 0x40, 0x01, 0xC0, /*"时",0*/ }; static const unsigned char PROGMEM jian[]{ 0x4F, 0xE0, 0x20, 0x20, 0x00, 0x20, 0x5F, 0xA0, 0x50, 0xA0, 0x50, 0xA0, 0x5F, 0xA0, 0x50, 0xA0, 0x50, 0xA0, 0x5F, 0xA0, 0x40, 0x20, 0x40, 0xE0, /*"间",0*/ }; static const unsigned char PROGMEM tong[]{ 0x9F, 0x80, 0x44, 0x80, 0x03, 0x00, 0x1F, 0xC0, 0xD2, 0x40, 0x5F, 0xC0, 0x52, 0x40, 0x5F, 0xC0, 0x52, 0x40, 0x52, 0xC0, 0x40, 0x00, 0xBF, 0xE0, /*"通",0*/ }; static const unsigned char PROGMEM xin[]{ 0x40, 0x00, 0x2F, 0x80, 0x04, 0x80, 0x04, 0x80, 0xE4, 0x80, 0x2F, 0x80, 0x24, 0x80, 0x24, 0x80, 0x24, 0x80, 0x34, 0xA0, 0x24, 0x60, 0x04, 0x20, /*"讯",1*/ }; static const unsigned char PROGMEM zhong[]{ 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x7F, 0xC0, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x7F, 0xC0, 0x44, 0x40, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, /*"中",2*/ }; static const unsigned char PROGMEM duan[]{ 0x10, 0x20, 0x55, 0xC0, 0xB9, 0x00, 0x91, 0x00, 0xFD, 0xE0, 0x91, 0x40, 0xB9, 0x40, 0xD5, 0x40, 0x91, 0x40, 0x91, 0x40, 0xFD, 0x40, 0x02, 0x40, /*"断",3*/ }; static const unsigned char PROGMEM guo[]{ 0xFF, 0xE0, 0x80, 0x20, 0xBF, 0xA0, 0x84, 0x20, 0x84, 0x20, 0xBF, 0xA0, 0x85, 0x20, 0x84, 0xA0, 0xFF, 0xE0, 0x80, 0x20, 0xFF, 0xE0, 0x80, 0x20, /*"国",1*/ }; static const unsigned char PROGMEM zhi[]{ 0x10, 0x20, 0x50, 0x20, 0x7D, 0x20, 0x91, 0x20, 0xFF, 0x20, 0x11, 0x20, 0x7D, 0x20, 0x55, 0x20, 0x55, 0x20, 0x54, 0x20, 0x5C, 0x20, 0x10, 0xE0, /*"制",2*/ }; static const unsigned char PROGMEM zao[]{ 0x82, 0x00, 0x52, 0x00, 0x1F, 0xC0, 0x22, 0x00, 0xC2, 0x00, 0x7F, 0xE0, 0x40, 0x00, 0x5F, 0xC0, 0x50, 0x40, 0x5F, 0xC0, 0x40, 0x00, 0xBF, 0xE0, /*"造",3*/ }; static const unsigned char PROGMEM zan[]{ 0x20, 0xC0, 0xFB, 0x00, 0x52, 0x00, 0x7B, 0xE0, 0x12, 0x40, 0xFA, 0x40, 0x14, 0x40, 0x3F, 0x80, 0x20, 0x80, 0x3F, 0x80, 0x20, 0x80, 0x3F, 0x80, /*"暂",0*/ }; static const unsigned char PROGMEM ting[]{ 0x11, 0x00, 0x1F, 0xE0, 0x20, 0x00, 0x27, 0xC0, 0x64, 0x40, 0xA7, 0xC0, 0x20, 0x00, 0x2F, 0xE0, 0x28, 0x20, 0x27, 0xC0, 0x21, 0x00, 0x23, 0x00, /*"停",1*/ }; static const unsigned char PROGMEM deng[]{ 0x42, 0x00, 0x7B, 0xE0, 0x94, 0x80, 0x04, 0x00, 0x7F, 0xC0, 0x04, 0x00, 0xFF, 0xE0, 0x01, 0x00, 0xFF, 0xE0, 0x21, 0x00, 0x11, 0x00, 0x07, 0x00, /*"等",0*/ }; static const unsigned char PROGMEM dai[]{ 0x11, 0x00, 0x21, 0x00, 0x47, 0xC0, 0x91, 0x00, 0x2F, 0xE0, 0x60, 0x80, 0xAF, 0xE0, 0x20, 0x80, 0x24, 0x80, 0x22, 0x80, 0x20, 0x80, 0x23, 0x80, /*"待",1*/ }; static const unsigned char PROGMEM jie[]{ 0x22, 0x00, 0x21, 0x00, 0x2F, 0xE0, 0xF4, 0x40, 0x22, 0x80, 0x2F, 0xE0, 0x31, 0x00, 0xEF, 0xE0, 0x22, 0x40, 0x26, 0x40, 0x21, 0x80, 0x6E, 0x60, /*"接",2*/ }; static const unsigned char PROGMEM shou[]{ 0x12, 0x00, 0x92, 0x00, 0x92, 0x00, 0x93, 0xE0, 0x94, 0x40, 0x9A, 0x40, 0x92, 0x40, 0xB2, 0x80, 0xD1, 0x00, 0x92, 0x80, 0x14, 0x40, 0x18, 0x20, /*"收",3*/ }; Adafruit_SSD1306 oled(128, 64, &Wire, -1); RF24 radio(6, 7); // CE, CSN const byte address[6] = "0000"; const byte address2[6] = "Space.ST"; int size = 12; //中文字体大小 float a = 0; // 初始化a int time = 0; // 初始化time float b; float c; void setup() { pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); Serial.begin(115200); if (!radio.begin()) { Serial.println("初始化失败"); return; } Serial.println("初始化成功"); radio.setPALevel(RF24_PA_MIN); radio.openReadingPipe(0, address); radio.openReadingPipe(1, address2); radio.startListening(); // 开启接收模式 oled.begin(SSD1306_SWITCHCAPVCC, 0x3c); oled.clearDisplay(); oled.setTextSize(1); oled.setTextColor(1); for (int progress = 0; progress <= 100; progress++) { oled.clearDisplay(); oled.setCursor(20, 0); oled.print("@Space-Traveler"); oled.drawBitmap(39, 17, zhong, size, size, 1); oled.drawBitmap(52, 17, guo, size, size, 1); oled.drawBitmap(65, 17, zhi, size, size, 1); oled.drawBitmap(78, 17, zao, size, size, 1); oled.fillRect(10, 55, progress + 10, 10, 1); // Draw progress bar oled.setCursor(25, 39); oled.print("Progress: "); oled.print(progress); oled.print("%"); oled.display(); } delay(1000); // Wait for a second at the end } void loop() { b = a / 1000 * 9.8; if (c < b) { c = b; } uint8_t pipe; if (radio.available(&pipe)) { // 使用whatPipe函数检查哪个管道有数据 if (pipe == 0) { radio.read(&a, sizeof(a)); } else if (pipe == 1) { // 读取数字数据 radio.read(&time, sizeof(time)); } oled.clearDisplay(); oled.drawBitmap(0, 0, sh, size, size, 1); oled.drawBitmap(13, 0, shi, size, size, 1); oled.setCursor(25, 5); oled.print(":"); oled.setCursor(30, 5); oled.print(b); oled.println("N"); oled.drawBitmap(0, 20, zui, size, size, 1); oled.drawBitmap(13, 20, da, size, size, 1); oled.setCursor(25, 25); oled.print(":"); oled.setCursor(30, 25); oled.print(c); oled.println("N"); oled.drawBitmap(0, 40, shi2, size, size, 1); oled.drawBitmap(13, 40, jian, size, size, 1); oled.setCursor(25, 45); oled.print(":"); oled.setCursor(30, 45); oled.print(time); oled.println("s"); oled.display(); // 确保在显示新数据之前调用oled.display() Serial.print(b); Serial.print("N"); Serial.print(" "); Serial.print(time); Serial.println("s"); if (digitalRead(2) == 0) { c = 0; } if (digitalRead(3) == 0) { while (1) { oled.drawBitmap(100, 15, zan, size, size, 1); oled.drawBitmap(100, 28, ting, size, size, 1); oled.display(); if (digitalRead(2) == 0) { digitalWrite(2, 1); delay(200); return; } } } } else { oled.clearDisplay(); oled.drawBitmap(38, 25, tong, size, size, 1); oled.drawBitmap(51, 25, xin, size, size, 1); oled.drawBitmap(64, 25, zhong, size, size, 1); oled.drawBitmap(77, 25, duan, size, size, 1); oled.display(); } }
以上为本次试车Mcu使用的所有代码
从我朋友那篇文章里原视频中,他的数据是采集到了的,120N左右(与理论推理偏差过大)
在试车之前已经调过校准了,目前不能断定也不能否决,是采集率的问题,虽然接收端的采集率只有20赫兹,但只是数据接收的速度过慢,但发送版的那部分数据采集是完全按照80赫兹进行工作,接收也可能是因为我额外加了oled作为显示,结果导致速率过慢了,这个是先前测试过的,但是为了方便观看就画蛇添足的加了一个
但这不能说明发送板采集有问题
目前暂时没有找到具体原因,测试之前,发送端的采集率达到80赫兹(不排除硬件问题),至于目前原因暂未找到,我们会进一步的进行查找和排除问题,另外如果我们的代码逻辑问题,希望大佬们能够指出
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |