五传感器键盘ㄱ字符输出乱码(Mojibake)问题排查请求
Let's break down why you're seeing garbled text instead of the expected "ㄱ" characters and walk through how to fix it:
Key Root Causes
Your problem almost certainly stems from Unicode/UTF-8 encoding mismatches between how you're sending the character and how the receiving device interprets it, plus some minor logic gaps in your code.
1. Incorrect Character Transmission
The Hangul character "ㄱ" (U+3131) requires 3 bytes in UTF-8 encoding (0xE3, 0x84, 0xB1). When you use bluetooth.write("ㄱ"), two issues often arise:
- If your Arduino code file isn't saved in UTF-8 format, the string literal "ㄱ" gets corrupted into invalid bytes before it even sends.
- Even if the file is UTF-8,
SoftwareSerial.write(const char*)sends each byte of the string individually—but if the receiving device isn't set to decode UTF-8, those 3 bytes get misinterpreted as separate ASCII characters, leading to mojibake.
2. Unintended Byte Sending (SensorPin2 Bug)
Looking at your code, SensorPin2 has a critical mistake:
if(FSR2 > 100) { bluetooth.write(FSR2); // Sends the sensor's numeric value, not the "ㄱ" character }
This sends the mapped analog sensor value (0-255) as a raw byte, which will definitely show up as garbage text instead of the intended character.
3. Repeated Triggering
Your current loop checks sensor values every 333ms and sends the character every time the sensor is above the threshold. If you hold the sensor down, it will spam "ㄱ" multiple times in quick succession, which can overwhelm the receiving device and cause byte loss or misinterpretation.
Step-by-Step Fixes
1. Force Correct UTF-8 Transmission
Instead of relying on string literals, send the exact UTF-8 byte sequence for "ㄱ" directly. This eliminates encoding ambiguity in your code:
// Define the UTF-8 bytes for "ㄱ" as a global constant const byte giyeok_utf8[] = {0xE3, 0x84, 0xB1}; // Replace your existing bluetooth.write("ㄱ") lines with: bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8));
2. Fix SensorPin2 Logic
Update the SensorPin2 block to send the correct character instead of the sensor value:
if(FSR2 > 100) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); }
3. Add Edge Detection to Avoid Repeated Sends
Modify your code to only send the character when the sensor is first pressed (instead of every loop iteration while it's held down). Add these global variables to track sensor states:
// Track previous sensor states to detect press events bool prevFSR1 = false; bool prevFSR2 = false; bool prevFSR5 = false;
Then update your loop logic for each sensor:
// Sensor 1 handling with edge detection bool currentFSR1 = (FSR1 > 100); if(currentFSR1 && !prevFSR1) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR1 = currentFSR1; // Sensor 2 handling with edge detection bool currentFSR2 = (FSR2 > 100); if(currentFSR2 && !prevFSR2) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR2 = currentFSR2; // Sensor 5 handling with edge detection bool currentFSR5 = (FSR5 > 100); if(currentFSR5 && !prevFSR5) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR5 = currentFSR5;
4. Verify Receiving Device Encoding
Make sure the device receiving the Bluetooth data (phone, computer, etc.) is set to decode incoming text as UTF-8. Most serial/bluetooth tools let you select the encoding in their settings—this is critical for displaying the character correctly.
Full Modified Code Snippet
Here's how your updated code should look with all fixes applied:
#include <SoftwareSerial.h> #include<Wire.h> #define BT_RXD 8 #define BT_TXD 7 SoftwareSerial bluetooth(BT_RXD, BT_TXD); int SensorPin1 = A0; int SensorPin2 = A1; int SensorPin3 = A2; int SensorPin4 = A3; int SensorPin5 = A4; const int MPU_addr=0x68; int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; // UTF-8 bytes for Hangul character "ㄱ" (U+3131) const byte giyeok_utf8[] = {0xE3, 0x84, 0xB1}; // Previous sensor states for edge detection bool prevFSR1 = false; bool prevFSR2 = false; bool prevFSR5 = false; void setup() { Wire.begin(); Wire.beginTransmission(MPU_addr); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); bluetooth.begin(9600); } void loop() { int SensorReading1 = analogRead(SensorPin1); int SensorReading2 = analogRead(SensorPin2); int SensorReading3 = analogRead(SensorPin3); int SensorReading4 = analogRead(SensorPin4); int SensorReading5 = analogRead(SensorPin5); int FSR1 = map(SensorReading1, 0, 1024, 0, 255); int FSR2 = map(SensorReading2, 0, 1024, 0, 255); int FSR3 = map(SensorReading3, 0, 1024, 0, 255); int FSR4 = map(SensorReading4, 0, 1024, 0, 255); int FSR5 = map(SensorReading5, 0, 1024, 0, 255); Wire.beginTransmission(MPU_addr); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); AcX=Wire.read() << 8|Wire.read(); AcY=Wire.read() << 8|Wire.read(); AcZ=Wire.read() << 8|Wire.read(); Tmp=Wire.read() << 8|Wire.read(); GyX=Wire.read() << 8|Wire.read(); GyY=Wire.read() << 8|Wire.read(); GyZ=Wire.read() << 8|Wire.read(); Serial.print("AcX = "); Serial.print(AcX); Serial.print(" | AcY = "); Serial.print(AcY); Serial.print(" | AcZ = "); Serial.println(AcZ); // Sensor 1 handling bool currentFSR1 = (FSR1 > 100); if(currentFSR1 && !prevFSR1) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR1 = currentFSR1; // Sensor 2 fixed handling bool currentFSR2 = (FSR2 > 100); if(currentFSR2 && !prevFSR2) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR2 = currentFSR2; // Sensor 3 (no action as per original code) // Sensor 4 (no action as per original code) // Sensor 5 handling bool currentFSR5 = (FSR5 > 100); if(currentFSR5 && !prevFSR5) { bluetooth.write(giyeok_utf8, sizeof(giyeok_utf8)); } prevFSR5 = currentFSR5; if (bluetooth.available()) { //Serial.write(bluetooth.read()); } if (Serial.available()) { //bluetooth.write(FSR); } delay(333); }
内容的提问来源于stack exchange,提问作者Taejoo Park

