簡體   English   中英

將數據寫入arduino python

[英]Writing data to arduino python

我正在嘗試使用此草圖將數據從python寫入串行

import serial
import smtplib
import time
s=serial.Serial('/dev/tty.usbserial-AH01LLHS',9600)
precx=500
ist=30
i=0
while True:
    s.write('1')
    stringa=s.readline()
    array=stringa.split(',')
    x=int(array[0])
    y=int(array[1])
    z=int(array[2])
    print(x,y,z)
    if(precx!=500):
        diffx=abs(x-precx)
        diffy=abs(y-precy)
        diffz=abs(z-precz)

        if((diffx>ist)|(diffy>ist)|(diffz>ist)):
            print('Ohu god',i)
            i+=1
            #time.sleep(2)
    precx=x
    precy=y
    precz=z

但是,當我執行程序時,在控制台上什么也看不到,並且Arduino Rx led關閉了。

這是我的Arduino草圖(nano atmega 328):

//Add the SPI library so we can communicate with the ADXL345 sensor
#include <SPI.h>

//Assign the Chip Select signal to pin 10.
int CS=10;

//This is a list of some of the registers available on the ADXL345.
//To learn more about these and the rest of the registers on the ADXL345, read the datasheet!
char POWER_CTL = 0x2D;  //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
//This buffer will hold values read from the ADXL345 registers.
char values[10];
//These variables will be used to hold the x,y and z axis accelerometer values.
int x,y,z;
boolean snd;
void setup(){ 
  //Initiate an SPI communication instance.
  SPI.begin();
  //Configure the SPI connection for the ADXL345.
  SPI.setDataMode(SPI_MODE3);
  //Create a serial connection to display the data on the terminal.
  Serial.begin(9600);

  //Set up the Chip Select pin to be an output from the Arduino.
  pinMode(CS, OUTPUT);
  //Before communication starts, the Chip Select pin needs to be set high.
  digitalWrite(CS, HIGH);

  //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(DATA_FORMAT, 0x01);
  //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
  writeRegister(POWER_CTL, 0x08);  //Measurement mode  
}

void loop(){
  //snd=true;
  //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
  //The results of the read operation will get stored to the values[] buffer.
  readRegister(DATAX0, 6, values);

  //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
  //The X value is stored in values[0] and values[1].
  x = ((int)values[1]<<8)|(int)values[0];
  //The Y value is stored in values[2] and values[3].
  y = ((int)values[3]<<8)|(int)values[2];
  //The Z value is stored in values[4] and values[5].
  z = ((int)values[5]<<8)|(int)values[4];
 if (Serial.available() > 0) {
   if(Serial.read()=='1'){
     snd=true;
   }
   else{
     snd=false;
   }
 }
 if(snd){
  //Print the results to the terminal.
  Serial.print(x, DEC);
  Serial.print(',');
  Serial.print(y, DEC);
  Serial.print(',');
  Serial.print(z, DEC);
  Serial.println("");
  delay(10); 
 }

}

//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.
void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(CS, HIGH);
}

//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit of the register address should be set.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 needs to be set as well.
  if(numBytes > 1)address = address | 0x40;

  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(CS, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  //Set the Chips Select pin high to end the SPI packet.
  digitalWrite(CS, HIGH);
}

提前致謝。

您絕對應該檢查評論中的建議:

  • 使程序更簡單,使其始終在沒有“流控制”的情況下發送值(使用您發送的“ 1”字節),
  • 使用串行監視器檢查輸出。

首先,您應檢查在s.write('1')幫助之前和之后是否添加s.flush() 然后,您可能也想在您的arduino代碼中添加flush()

對我而言,“流控制”算法的初始化確實看起來像是一個飢餓的問題。 在紙上看起來不錯,但在現實生活中可能並非如此。 通常,Arduino開始填充主機串行端口的緩沖區時會發送大量垃圾。 反之亦然。 因此,您可能會得到一個完全沒有用的!@#$@#%@#%!@#$ ,而不是在arduino端設置為1

因此,在任何一方,進入循環之前,您都應該添加一個初始化協議。 arduino發送READY ,主機發送READY ,您清空所有內容,直到兩邊都READY 看起來像這樣:

void setup() {
    Serial.begin(9600);
    Serial.println('READY');
    Serial.flush();
    char ch1 = 0, ch2 = 0;
    char incomingByte = 0;
    while (ch1 != 'O' && ch2 != 'K') {
        ch1 = Serial.read();
        if (ch1 == 'O' && ch2 == 'K')
            break;
        ch2 = Serial.read();
    }
}

在python方面:

with serial.Serial('/dev/tty.usbserial-AH01LLHS',9600) as s:
    s.flush()
    ready = ""
    while ready != "READY":
        ready = s.readline()
        s.flush()
    while True:
        # ... you stuff

當然,這只是您可能會做的一個想法。 您可以使其更復雜或更簡單。 但是在進行此類流控制之前,您確實需要創建一個匯合點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM