如何将浮点值从Python发送到Arduino LCD?

时间:2019-03-25 22:54:53

标签: python arduino

我和我的同学一直在根据《教学指南》 https://www.instructables.com/id/Building-a-Simple-Pendulum-and-Measuring-Motion-Wi/进行这个项目,我们的想法是制作一个摆锤,计算g力(从摆锤的时间),然后在LCD上显示其值我们已连接到Arduino。我们启动并运行了代码(它计算周期),并且我们了解到Arduino必须进行某种类型的转换(utf-8)才能将其从电位计获得的值传递给Python。但是,当我们尝试将计算周期后得到的值发送回arduino并在LCD上显示时,它会显示634或其他类似值,我们尝试取代最初进行的解码,而不是其他编码的方式,但无法正常工作。我们无法检查它从串行获取的值,因为在python脚本运行时串行监视器根本无法打开。我们可以用来将Python脚本中计算出的浮点数“转移”到Arduino的最实际的方法是什么,以便我们可以计算g并将其显示在屏幕上。许多论坛建议不要将浮点数转换为字符串,因为arduino易于接收,但我们不确定这是否可行。我敢肯定这是一个简单的问题,但是我们似乎无法理解。如果您发现代码还有其他问题,请告诉我,我们知道它有点粗略。谢谢。

Python代码:

arduino = serial.Serial('COM3', 115200, timeout=.1) #Open connection to Arduino
samples = 200 #We will take this many readings
angle_data = np.zeros(samples) #Creates a vector for our angle data
time_data = np.zeros(samples) #Creates a vector of same length for time
i = 0;
calibrate = 123 #Value to zero potentiometer reading when pendulum is motionless, read from Arduino
while i!=samples:
    data = arduino.readline()[0:-2].decode('utf-8')
    if data:
        angle_data[i] = (float(data) - calibrate)*math.pi/180
        time_data[i] = time.perf_counter()
        print(angle_data[i])
        i = i + 1

min = np.min(angle_data)
print (min)
min_pos, = np.where(angle_data == min)
min_x = time_data[min_pos]
print (min_x)

nos_left = int(min_pos)
max = 0;
for i in range(nos_left,200):
   if angle_data[i] > max: max = angle_data[i]

print (max)
max_pos, = np.where(angle_data == max)
max_x = time_data[max_pos]
print (max_x)

period = (max_x - min_x) * 2
print (period)

gforce = (0.165 * 4 * (math.pi) * (math.pi)) / ((period) * (period))
print (gforce)

value_g = arduino.write(gforce)

plt.plot(time_data,angle_data,'ro')
plt.axis([0,time_data[samples-1],-math.pi,math.pi])
plt.xlabel("Time (seconds)")
plt.ylabel("Angle (Radians)")
plt.title("Pendulum Motion - Measured with Arduino and potentiometer")
plt.show()
arduino.close()

Arduino代码

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int period = 0;

void setup() {
  lcd.begin(16, 2);
  Serial.begin(115200); // use the same baud-rate as the python side
        pinMode(A0,INPUT);
        lcd.print("    Pendulo    ");
        int gforce = 0;

}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  // print the number of seconds since reset:


        int degrees;
        degrees = getDegree();
        Serial.println(degrees);
        Serial.println("\n");
        delay(50);

        if (Serial.available() > 0) {
                // read the incoming byte:
                gforce = Serial.read();

                Serial.print("I received: ");
                Serial.println(gforce, DEC);
        }

        lcd.setCursor(0, 1);
        lcd.print(gforce);


}

int getDegree()
{
  int sensor_value = analogRead(A0);
  float voltage;
  voltage = (float)sensor_value*5/1023;
  float degrees = (voltage*300)/5;
  return degrees;
}

1 个答案:

答案 0 :(得分:0)

对于Arduino Serial的parseFloat()方法来说,这似乎是一个很好的例子:

if (Serial.available() > 0) {

    /* instead of Serial.read(), use: */

    gforce = Serial.parseFloat();

    Serial.print("I received: ");
    Serial.println(gforce, DEC);
}

从本质上讲,即使它与其他非数字字符混合,它也会在接收到的串行数据中提取任何看起来像浮点的内容。

它还可以与软件序列号一起使用。