Сервопривод RPI Drive с помощью PWM (программирование проводки/C)

Я пытаюсь управлять сервоприводом с помощью Raspberry PI, используя ШИМ на выводе 18 GPIO. Я подключил установку, как вы можете видеть ниже. введите здесь описание изображения

Когда я управляю сервоприводом, я могу сделать это без каких-либо проблем. Команды, которые я использую, вы можете увидеть ниже.

     gpio -g mode 18 pwm
     gpio pwm-ms
     gpio pwmc 192
     gpio pwmr 2000
     gpio -g pwm 18 150
     gpio -g pwm 18 200

Это отлично работает, чтобы перейти на позицию без каких-либо проблем, но когда я пытаюсь сделать то же самое с программой C, используя wirepi, как вы можете видеть ниже.

#include <wiringPi.h>
#include <stdio.h>

int main (void)
{
   printf ("Raspberry Pi wiringPi test program\n");
   wiringPiSetupGpio();
   pinMode (18, PWM_OUTPUT) ;
   pwmSetMode (PWM_MODE_MS);
   pwmSetRange (2000);
   pwmSetClock (192);
   pwmWrite(18,150);
   delay(1000);
   pwmWrite(18,200);
   return 0;
}

Программа и Raspberry Pi ломаются, поэтому мне приходится перезагружать их. Кто-нибудь знает, что я делаю неправильно и как я могу решить проблему, это очень расстраивает?


person sanderfcb95    schedule 09.05.2017    source источник
comment
Вероятно, вам нужна какая-то защита от переходных процессов и электростатического разряда. Добавьте несколько диодов TVS с немного более высоким напряжением, чем ШИМ, и несколько последовательных резисторов. Но это тема для electronics.stackexchange.com. А еще есть raspberrypi.stackexchange.com.   -  person Lundin    schedule 09.05.2017
comment
о да, я забыл, что поместил его туда :p   -  person sanderfcb95    schedule 09.05.2017
comment
Вы читали руководство по wiringPiSetupGpio? Это идентично приведенному выше, однако это позволяет вызывающим программам напрямую использовать номера контактов Broadcom GPIO без переназначения. Как и выше, эта функция должна вызываться с привилегиями root, и обратите внимание, что некоторые контакты отличаются от плат версии 1 и версии 2.   -  person LPs    schedule 09.05.2017
comment
Но почему это работает, когда я использую wirepi в c, чтобы просто мигать светодиодом с помощью wirepi, у меня просто проблемы при использовании PWM   -  person sanderfcb95    schedule 09.05.2017
comment
Даже в новейших версиях wiredPi функциональность PWM требует, чтобы вы запускали свою программу с привилегиями root (т.е. sudo). Из-за этого вы испытываете проблему сбоя / перезагрузки. Чтобы обойти требование sudo, вам потребуется использовать цифровой потенциометр или цифро-аналоговый преобразователь вместо встроенной функции ШИМ.   -  person stevieb    schedule 09.05.2017
comment
Я не использовал wirepi, поэтому не знаю, имеет это значение или нет, но ваша линия PWM подключена к контакту 18, а не к GPIO 18. GPIO 18 находится на контакте 12.   -  person b_laoshi    schedule 05.08.2017
comment
Дополнительное примечание: используйте GPIO18 и 19 (каналы 0 и 1, ALT5, контакты 12 и 35) или GPIO12 и 13 (каналы 0 и 1, ALT0, контакты 32 и 33) для hardware_GPIO!   -  person gue22    schedule 28.03.2018


Ответы (2)


Я потратил недели на управление двумя сервоприводами (SG90) с помощью WiringPi и программирования на C, есть три вещи, которые я рекомендую.

1. Использование BCM GPIO вместо WiringPi Pin, поскольку для управления более чем одним сервоприводом может потребоваться более одного контакта, например 1(WiringPi Pin)/18(BCM GPIO) для другого сервопривода. Для версии RPi3 B+ он дает доступ к двум каналам для аппаратного ШИМ. . Канал 0 на gpios 12/18 и канал 1 на gpios 13/19, это легко и не нужно беспокоиться о сопоставлении контактов, если вы используете BCM GPIO.

2. Лучше убедитесь, что есть только одна программа доступа PWM. булавки за один раз. Основываясь на моем опыте, если вы обнаружите, что использование такой команды, как «gpio -g pwm 18 25», работает, но в противном случае использование кода, такого как «pwmWrite(18, 25)», не дает никаких ответов сервопривода, возможно, попробуйте «ps -A», чтобы убедиться, что какая-либо другая программа пытается получить доступ к вашему сервоприводу. .

3. Последнее и самое сложное для меня, когда я выполняю pwmWrite(18, 25)" на PWM. pin 18, срабатывает та же инструкция на PWM. pin 12, что означает, что pwmWrite(18, 25) срабатывает pwmWrite(12, 25). в режим ввода и установите для них раскрывающийся список.

Для подробностей коды для управления двумя сервоприводами с ШИМ. Канал 0 на gpios 12/18.

Основная функция:

void servo_init() {
    servo_open(0);
    delay(DELAY_SERVO);
    servo_open(1);}

и

void servo_open(int servo) {
switch (servo) {
    case 0:
        pullUpDnControl(SERVO_0, PUD_OFF);
        pinMode(SERVO_0, PWM_OUTPUT);
        pwmSetMode(PWM_MODE_MS);
        pwmSetClock(PWM_CHANNEL_0_CLOCK);
        pwmSetRange(PWM_CHANNEL_0_RANGE);
        break;
    case 1:
        pullUpDnControl(SERVO_1, PUD_OFF);
        pinMode(SERVO_1, PWM_OUTPUT);
        pwmSetMode(PWM_MODE_MS);
        pwmSetClock(PWM_CHANNEL_0_CLOCK);
        pwmSetRange(PWM_CHANNEL_0_RANGE);
        break;  
    default:

        break;
}}

и

void servo_close(int servo) {

switch (servo) {
    case 0:
        pinMode(SERVO_0, INPUT);
        pullUpDnControl(SERVO_0, PUD_DOWN);
        break;
    case 1:
        pinMode(SERVO_1, INPUT);
        pullUpDnControl(SERVO_1, PUD_DOWN);
        break;  
    default:

        break;
}}

и

void servo(int servo, int angle) {
switch (servo) {
    case 0:
        servo = SERVO_0;
        break;
    case 1:
        servo = SERVO_1;
        break;  
    default:
        servo = -1;
        break;
}
switch (angle) {
    case 90:
        value = 25;
        break;
    case -90:
        value = 10;
        break;
    case 0:
        value = 14;
        break;  
    default:
        break;
}
if (servo == -1) return;
pwmWrite(servo, value);}

Поворот одного сервопривода, подключенного к 18 (BCM GPIO)

Закройте другие, прежде чем вы собираетесь вращать один

servo_close(1);
delay(DELAY_SERVO);

Повернуть

servo(0, 90);
delay(3*DELAY_MAGIC);
servo(0, 0);

Сбросьте все сервоприводы к их начальным углам для исправления случайного дрожания сервоприводов.

delay(DELAY_SERVO);
servo_init();

Проверьте больше исходного кода и информацию о сервоприводе и датчике на Raspberry: МОЙ GitHub

person 牟家宏    schedule 15.07.2019

Попробуйте sudo ./servo Надеюсь, это сработает.

person ROHAN YADAV    schedule 06.07.2021