gpt4 book ai didi

Python- Firmata 和 Arduino,影响 Firmata 的脚本结构

转载 作者:太空宇宙 更新时间:2023-11-03 19:00:07 25 4
gpt4 key购买 nike

当使用此脚本使引脚 12 上的 LED 闪烁时,该脚本不会越过引脚 12 设置为高电平的第 27 行。没有错误消息。

    import json
import urllib
from firmata import *
from pprint import pprint
import time
import serial

countTweet = 0
a = Arduino('COM13') #Insert this before the while loop = it never actually works
a.delay(2)

while True:
try:
response = urllib.urlopen('http://search.twitter.com/search.json?q=%23happy&result_type=recent&rpp=1&filter:retweets').read()
except IOError:
pprint('no internet connection')
time.sleep(5)
continue
j = json.loads(response)
if j['results']:
text = j['results'][0]['text']
tID = j['results'][0]['id']
else:
pprint('bad JSON')
if countTweet != 0 and lastID != tID:
pprint('new ID')
a.pin_mode(12, firmata.OUTPUT) #Gets stuck here
a.delay(2)
a.digital_write(12, firmata.HIGH)
a.delay(2)
a.digital_write(12, firmata.LOW)
pprint('done firmata')
lastID = tID
pprint (text)
pprint ('1')
else:
pprint("FLC") #First loop complete: To gather the existing tweet before we start
lastID = tID
countTweet += 1
time.sleep(15)

如何构造此脚本以便 Firmata/Serial 在每个循环上运行?我有兴趣了解为什么上面的脚本根本不起作用,但下面的 LED 示例却可以。

    from firmata import * 

a = Arduino('COM13')
a.pin_mode(12, firmata.OUTPUT)
a.delay(2)

while True:
a.digital_write(12, firmata.HIGH)
a.delay(2)
a.digital_write(12, firmata.LOW)
a.delay(2)

Arduino 正在运行 oldStandardFirmata

#include <EEPROM.h>
#include <Firmata.h>

/*==============================================================================
* GLOBAL VARIABLES
*============================================================================*/

/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins

/* digital pins */
byte reportPINs[TOTAL_PORTS]; // PIN == input port
byte previousPINs[TOTAL_PORTS]; // PIN == input port
byte pinStatus[TOTAL_PINS]; // store pin status, default OUTPUT
byte portStatus[TOTAL_PORTS];

/* timer variables */
unsigned long currentMillis; // store the current value from millis()
unsigned long previousMillis; // for comparison with currentMillis


/*==============================================================================
* FUNCTIONS
*============================================================================*/

void outputPort(byte portNumber, byte portValue)
{
portValue = portValue &~ portStatus[portNumber];
if(previousPINs[portNumber] != portValue) {
Firmata.sendDigitalPort(portNumber, portValue);
previousPINs[portNumber] = portValue;
Firmata.sendDigitalPort(portNumber, portValue);
}
}

/* -----------------------------------------------------------------------------
* check all the active digital inputs for change of state, then add any events
* to the Serial output queue using Serial.print() */
void checkDigitalInputs(void)
{
byte i, tmp;
for(i=0; i < TOTAL_PORTS; i++) {
if(reportPINs[i]) {
switch(i) {
case 0: outputPort(0, PIND &~ B00000011); break; // ignore Rx/Tx 0/1
case 1: outputPort(1, PINB); break;
case 2: outputPort(2, PINC); break;
}
}
}
}

// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
* two bit-arrays that track Digital I/O and PWM status
*/
void setPinModeCallback(byte pin, int mode) {
byte port = 0;
byte offset = 0;

if (pin < 8) {
port = 0;
offset = 0;
} else if (pin < 14) {
port = 1;
offset = 8;
} else if (pin < 22) {
port = 2;
offset = 14;
}

if(pin > 1) { // ignore RxTx (pins 0 and 1)
pinStatus[pin] = mode;
switch(mode) {
case INPUT:
pinMode(pin, INPUT);
portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
break;
case OUTPUT:
digitalWrite(pin, LOW); // disable PWM
case PWM:
pinMode(pin, OUTPUT);
portStatus[port] = portStatus[port] | (1 << (pin - offset));
break;
//case ANALOG: // TODO figure this out
default:
Firmata.sendString("");
}
// TODO: save status to EEPROM here, if changed
}
}

void analogWriteCallback(byte pin, int value)
{
setPinModeCallback(pin,PWM);
analogWrite(pin, value);
}

void digitalWriteCallback(byte port, int value)
{
switch(port) {
case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1)
// 0xFF03 == B1111111100000011 0x03 == B00000011
PORTD = (value &~ 0xFF03) | (PORTD & 0x03);
break;
case 1: // pins 8-13 (14,15 are disabled for the crystal)
PORTB = (byte)value;
break;
case 2: // analog pins used as digital
PORTC = (byte)value;
break;
}
}

// -----------------------------------------------------------------------------
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
*/
//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
//}
void reportAnalogCallback(byte pin, int value)
{
if(value == 0) {
analogInputsToReport = analogInputsToReport &~ (1 << pin);
}
else { // everything but 0 enables reporting of that pin
analogInputsToReport = analogInputsToReport | (1 << pin);
}
// TODO: save status to EEPROM here, if changed
}

void reportDigitalCallback(byte port, int value)
{
reportPINs[port] = (byte)value;
if(port == 2) // turn off analog reporting when used as digital
analogInputsToReport = 0;
}

/*==============================================================================
* SETUP()
*============================================================================*/
void setup()
{
byte i;

Firmata.setFirmwareVersion(2, 0);

Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
Firmata.attach(SET_PIN_MODE, setPinModeCallback);

portStatus[0] = B00000011; // ignore Tx/RX pins
portStatus[1] = B11000000; // ignore 14/15 pins
portStatus[2] = B00000000;

// for(i=0; i<TOTAL_PINS; ++i) { // TODO make this work with analogs
for(i=0; i<14; ++i) {
setPinModeCallback(i,OUTPUT);
}
// set all outputs to 0 to make sure internal pull-up resistors are off
PORTB = 0; // pins 8-15
PORTC = 0; // analog port
PORTD = 0; // pins 0-7

// TODO rethink the init, perhaps it should report analog on default
for(i=0; i<TOTAL_PORTS; ++i) {
reportPINs[i] = false;
}
// TODO: load state from EEPROM here

/* send digital inputs here, if enabled, to set the initial state on the
* host computer, since once in the loop(), this firmware will only send
* digital data on change. */
if(reportPINs[0]) outputPort(0, PIND &~ B00000011); // ignore Rx/Tx 0/1
if(reportPINs[1]) outputPort(1, PINB);
if(reportPINs[2]) outputPort(2, PINC);

Firmata.begin(115200);
}

/*==============================================================================
* LOOP()
*============================================================================*/
void loop()
{
/* DIGITALREAD - as fast as possible, check for changes and output them to the
* FTDI buffer using Serial.print() */
checkDigitalInputs();
currentMillis = millis();
if(currentMillis - previousMillis > 20) {
previousMillis += 20; // run this every 20ms
/* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
* all serialReads at once, i.e. empty the buffer */
while(Firmata.available())
Firmata.processInput();
/* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
* 60 bytes. use a timer to sending an event character every 4 ms to
* trigger the buffer to dump. */

/* ANALOGREAD - right after the event character, do all of the
* analogReads(). These only need to be done every 4ms. */
for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
if( analogInputsToReport & (1 << analogPin) ) {
Firmata.sendAnalog(analogPin, analogRead(analogPin));
}
}
}
}

最佳答案

我的印象是您与 arduino 的串行通信无法正常工作。我看不到你在哪里以及如何打开串口和端口参数。您的程序卡在尝试与串行端口通信的第一行。

    import serial
ser = serial.Serial()
ser.port = "/dev/ttyUSB0" # may be called something different
ser.baudrate = 115200 # may be different
ser.open()

关于Python- Firmata 和 Arduino,影响 Firmata 的脚本结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16234776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com