Hai Arduinos Gửi dữ liệu qua Pin Analog?


7

Những gì tôi muốn làm là cho phép Arduino Một để gửi một số giá trị không đổi để Arduino B .

Tôi cảm thấy có gì đó không đúng với cách tiếp cận của tôi, nhưng tôi không thể tìm ra nó là gì.

Vì vậy, trong sơ đồ bên dưới, bạn sẽ thấy Arduino A cài đặt Pin tương tự 0 là OUTPUT và viết giá trị 2 cứ sau 500ms. Trên Arduino B, chúng ta có Analog Pin 0 được đặt thành INPUT để nhận và in dữ liệu thành Nối tiếp. Các chân GND của cả Arduinos cũng được kết nối.

Khi thiết lập này được thực thi, Arduino B liên tục nhận dữ liệu dưới dạng số có 3 chữ số bắt đầu bằng 3XX. Tôi bắt đầu tin rằng đây là giá trị điện áp?

Điều gì vốn đã sai với ý tưởng này?

nhập mô tả hình ảnh ở đây


Bạn đã thử kết nối các chân đất với nhau chưa?

@Kynit: Có, các chân GND đã được kết nối (quên vẽ nó).

Không, tôi không sống trong thế giới EE, nhưng tôi có thể thử! Câu trả lời tuyệt vời ở đây, tôi đang cố gắng tiếp thu tất cả. Sẽ cập nhật sớm.
lucidgold

@lucidgold Tóm tắt khi bắt đầu câu trả lời của tôi cho bạn biết chính xác những gì cần làm. Phần còn lại cho bạn biết lý do tại sao.
Russell McMahon

Câu trả lời:


9

Câu trả lời này cung cấp cả kiến ​​thức cụ thể về Arduino và kiến ​​thức điện nói chung - cả hai đều cần thiết cho một giải pháp tốt (không may).


Tóm lược

Để thực hiện chuyển đổi tương tự Arduino sang tương tự:

  • Sử dụng analogWrite (pin, giá trị) trên pin kỹ thuật số hợp lệ (xem bên dưới)

  • Sử dụng analogRead (pin) trên pin đầu vào analog hợp lệ.

  • Kết nối một điện trở nối tiếp giữa hai chân - giả sử 10k.
    Đặt một tụ điện từ đầu vào tương tự xuống đất, nói 100 nF đến 10 uF.

R & C hoạt động như một bộ lọc thông thấp để chuyển đổi PWM sang DC.
Chi tiết bên dưới.


Chân analog Arduino chỉ dành cho đầu vào analog, không cho đầu ra analog.
Vì vậy, cố gắng thực hiện tương tự trên một pin tương tự làm thất bại nỗ lực của bạn.

Arduino analogWrite (pin, value) chỉ hoạt động trên các chân Digital và sau đó chỉ trên tập hợp con của các chân kỹ thuật số có khả năng PWM. Đây thường là chân kỹ thuật số 3 5 6 9 10 11.

"analogWrite (pin, value) tạo ra như những gì người khác đã nói - tín hiệu PWM - sóng vuông với đường ray với tỷ lệ không gian đánh dấu thay đổi để giá trị DC trung bình thay đổi
.
Trong đó 'giá trị' đến từ analogWrite (pin, value)

Để chuyển đổi PWM thành DC đủ tốt, cần có bộ lọc thông thấp với mức cắt thấp hơn một chút so với tốc độ khung hình PWM. Tốc độ khung hình của Arduino AFAIK là khoảng 800 Hz - vì vậy các thành phần thường cao hơn thế. Một bộ lọc RC đơn giản trong đó R x C hữu ích hơn khoảng 0,001S sẽ bắt đầu hoạt động. RC lớn hơn mượt mà hơn nhưng với các hiệu ứng phụ. Sử dụng nắp gốm 10 uF và điện trở 10k có lẽ là ổn. 10 uF x 10k = 0,1S. 1uF và 1k = 0,001 s = cận biên. Một nắp điện phân có thể được sử dụng nhưng dòng rò có thể ảnh hưởng một chút đến độ chính xác. Vì thế -


Từ một nơi nào đó trên đất Arduino (không rõ) tôi đã sao chép tài liệu bên dưới.
Điều này KHÔNG có trong tài liệu tham khảo cơ bản, nhưng nên được.

  • Ghi một giá trị tương tự (sóng PWM) vào chân. Có thể được sử dụng để chiếu sáng đèn LED ở các độ sáng khác nhau hoặc điều khiển động cơ ở nhiều tốc độ khác nhau. Sau một cuộc gọi đến analogWrite (), pin sẽ tạo ra một sóng vuông ổn định của chu kỳ nhiệm vụ được chỉ định cho đến khi cuộc gọi tiếp theo tới analogWrite () (hoặc một cuộc gọi đến digitalRead () hoặc digitalWrite () trên cùng một pin). Tần số của tín hiệu PWM trên hầu hết các chân là khoảng 490 Hz. Trên bảng Uno và các bảng tương tự, chân 5 và 6 có tần số xấp xỉ 980 Hz. Các chân 3 và 11 trên Leonardo cũng chạy ở tần số 980 Hz.

    Trên hầu hết các bo mạch Arduino (những máy có ATmega168 hoặc ATmega328), chức năng này hoạt động trên các chân 3, 5, 6, 9, 10 và 11. Trên Arduino Mega, nó hoạt động trên các chân 2 - 13 và 44 - 46. Arduino cũ hơn các bảng có ATmega8 chỉ hỗ trợ analogWrite () trên các chân 9, 10 và 11.

    Arduino Do hỗ trợ analogWrite () trên các chân từ 2 đến 13, cộng với các chân DAC0 và DAC1. Không giống như các chân PWM, DAC0 và DAC1 là các bộ chuyển đổi Digital sang Analog và hoạt động như các đầu ra analog thực sự.


3

analogWrite()trên Uno không thực sự xuất ra một giá trị tương tự. Nó tạo ra một sóng PWM có giá trị trung bình tương đương với giá trị đó. Nếu bạn muốn biến nó thành một giá trị tương tự thực sự thì bạn cần đặt nó thông qua bộ lọc thông thấp để loại bỏ các thành phần làm cho nó trở thành sóng PWM thay thế.


"Bộ lọc thông thấp" này là gì?

Bộ lọc thông thấp sẽ cắt các tần số cao (tức là các bit lượn sóng vuông của PWM). Google nó hoặc tìm xung quanh trang web này - có rất nhiều ví dụ.

Điều này hầu như không phải là duy nhất đối với arduino / ATmega; rất ít bộ vi điều khiển có chứa các bộ xử lý tín hiệu thực sự, ngoại trừ các khối sigma-delta được thiết kế riêng cho âm thanh.
Chris Stratton

2

Nếu mục đích của bạn là gửi một giá trị không đổi từ Arduino A đến Arduino B, thì một cách thực sự dễ dàng là sử dụng SoftwareSerial.

Giả sử bạn đang sử dụng Arduino Uno - bạn có thể sử dụng chân 2 và 3 cho SoftwareSerial (xem chân nào được hỗ trợ cho thiết bị nào tại http://arduino.cc/en/Reference/SoftwareSerial )

Kết nối chéo pin 2 và 3 từ Arduino A đến pin 3 và 2 của Arduino B. Bạn có thể gửi bất kỳ dữ liệu ngẫu nhiên nào giữa hai Arduinos bằng cách tải lên một bản phác thảo như sau trên mỗi cái. Bạn có thể sử dụng một chương trình như CoolTerm để mở "SerialMonitor" cho mỗi Arduino (sử dụng Arduino IDE, bạn chỉ có thể mở một màn hình mỗi lần)

Ưu điểm của phương pháp này so với sử dụng AnalogWrite / AnalogRead là với AnalogRead, bạn chỉ có thể nhận được 1024 giá trị, dựa trên điện áp. Với SoftwareSerial, bạn có thể gửi bất kỳ dữ liệu tùy ý.

// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup() {
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);

    mySerial.begin(9600);

    Serial.begin(9600);
 }

void loop() {

    if ( mySerial.available() )
    {
         while ( mySerial.available() )
             Serial.write(mySerial.read());

         Serial.println();
    }

    if ( Serial.available() )
    {
        delay(5);

        while ( Serial.available() )
            mySerial.write( Serial.read() );
    }

}

0

Như đã đề cập ở trên, sử dụng analogWrite sẽ không hoạt động. (Tôi cho rằng bạn có thể lấy mẫu tín hiệu tương tự được cho là có vòng lặp nhanh và đo chu kỳ nhiệm vụ ...)

Tại sao không sử dụng SoftwareSerialđể gửi dữ liệu giữa hai Arduinos?

Đó là một thư viện tạo ra một cổng nối tiếp khác, hoàn toàn bằng phần mềm, vì vậy nó độc lập với UART chính trên cổng USB.

Nó đã là một phần của IDE và nó rất dễ sử dụng - trên thực tế, mã demo trên trang trợ giúp sẽ hoạt động cho bạn, chuyển bất kỳ ký tự nào từ cổng nối tiếp USB sang cổng nối tiếp phần mềm.


AnalogWrite hoàn toàn OK miễn là thêm một điện trở 1 x đơn giản và 1 x bộ lọc tụ điện được thêm vào (xem câu trả lời của tôi). Có thể có lý do chính đáng để sử dụng tương tự mà không rõ ràng ở đây.
Russell McMahon

0

Như những người khác đã chỉ ra, đề xuất ban đầu của bạn sẽ không hoạt động.

Bạn có thể sử dụng đầu ra PWM và bộ lọc có thể hoạt động (bạn sẽ cần một tụ điện và / hoặc điện trở khá lớn). Đầu vào ở đầu kia sẽ chỉ là xấp xỉ đầu ra (bạn có thể tính toán dựa trên kiến ​​thức chi tiết về các giá trị và tần số thành phần). Tùy thuộc vào tốc độ thay đổi giá trị, bạn có thể nhận được các giá trị khác nhau trên mỗi lần đọc.

Có nhiều cách tốt hơn. Theo đề xuất, nối tiếp sẽ hoạt động (cả phần cứng hoặc phần mềm tùy thuộc vào các yếu tố khác) và có lẽ là dễ nhất. Bạn có thể sử dụng bất kỳ giao thức giao tiếp phổ biến nào (I²C hoặc SPI) hoặc thậm chí gửi các giá trị qua IP.


0

Analog In thực hiện chính xác những gì nó nói - nó chỉ đọc (mẫu) các mức điện áp tương tự.

Sử dụng AnalogWrite (0,2) không tạo ra chân A0 trong Analog In để tạo ra điện áp 2 * AVCC / 1024, mà thay vào đó, làm cho chân D0 thực hiện điều đó thay vào đó. (Hầu hết các chân D0 trên bo mạch Arduino không có đầu ra PWM được liên kết với chúng, vì vậy hành vi sẽ không được xác định.) Trong thời gian đó, A0 của bạn không làm gì cả. (Tôi nghi ngờ nó nổi / không được kết nối, do đó giá trị 3xx. Có thể kiểm tra biểu dữ liệu để chắc chắn.)

Vậy chúng ta nên làm gì thay thế? Để bắt đầu, kết nối A0 của Arduino B với pin pwm của Arduino A. Nếu bạn đang sử dụng Uno, bạn có thể kết nối với bất kỳ chân nào 11,10,9,6,5,3. Sau đó, bạn có thể sử dụng mã:

int PWMPin = 11; int Tín hiệuLvl = 2; analogWrite (PWMPin, SignalLvl);

Hãy thử xem. Và bạn sẽ thấy rằng nó hoạt động ... loại.

Nhưng sau đó có một vấn đề. bài đọc của bạn sẽ gần với những gì bạn muốn, nhưng khá thất thường. Lý do một phần là do tín hiệu tương tự siêu không đáng tin cậy và chứa đầy nhiễu. Nhưng lý do chính thực sự là analogWrite của Arduino thực sự KHÔNG được thiết kế như một đầu ra tín hiệu tương tự. Nó là một PWM, xuất ra các mức GND và AVcc ở các khoảng thời gian khác nhau với tốc độ nhanh để nó xấp xỉ mức điện áp bạn muốn khi lấy trung bình.

Nếu bạn muốn thử nghiệm điều này, bạn có thể kết nối một điện trở và tụ điện với đầu ra, tạo ra bộ lọc thông thấp. (Đây là thông tin thêm: http://provideyourown.com/2011/analogwrite-convert-pwm-to-vol thế / )


Đã nói tất cả những điều đó, tôi đoán câu hỏi mà hầu hết chúng ta muốn hỏi là: có lý do nào khiến bạn muốn gửi dữ liệu qua analog không? Tín hiệu tương tự dễ bị nhiễu. Nếu độ trung thực của dữ liệu là quan trọng, tốt nhất bạn nên sử dụng giao tiếp nối tiếp như được đánh dấu bằng hầu hết các câu trả lời ở đây.

Để đơn giản, tôi đề nghị I2c chỉ sử dụng 2 dây để giao tiếp. Nếu tốc độ là điều cốt yếu (như, ghi tới 10.000 byte dữ liệu mỗi giây), bạn có thể thử SPI hoặc thậm chí giao tiếp song song.

Hy vọng điều này sẽ giúp và may mắn!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.