記事一覧

M5Stackでスピーカーからノイズ

M5Stackでスピーカーからノイズ


Noise from M5 Stack speakers



こんにちはRoboTakaoです。
Hello everyone! I'm RoboTakao!

M5Stackを使った二足歩行ロボットを製作中で、先日サーボを駆動するスケッチを紹介しましたが、
実はあのスケッチにはスピーカーからのノイズの対策を行っていました。
I am making a biped robot using M5Stack.
The other day, I introduced a sketch that drives a servo.
In fact, that sketch was taking measures against the noise from the speaker.

今回のロボットでは18個のサーボを駆動するのでサーボドライバのPAC9685の他に
ESP32Servoライブラリを使います。
Since this robot drives 18 servos, it uses ESP32Servo library besides PAC9685 servo driver.

NX10_113.png

ところがこのESP32Servoライブラリを使ったところ、スピーカーからかなりのノイズが出ることがわかりました。
However, when I used this ESP32Servo library, loud noise came out from the speakers.



回路図を見るとM5StackのスピーカーはNS4148というICにGPIO25のEPS32から入力することで音を出すようです。
When I look at the schematic, the M5Stack's speaker seems to make a sound by inputting from the EPS32 GPIO 25 to the NS4148 IC.

NX10_116.png


どうもEPS32Servoライブラリを使うとM5Stack上のどこかでカップリングしてノイズが伝播してスピーカを鳴らしていると推定されます。
Using the EPS32Servo library, it is estimated that coupling occurs somewhere on the M5Stack and noise is propagated and the speaker is sounding.

ネットで調べるとあえてGPIO25にDAC出力で”0”出力をしてノイズ低減する手法が有効のようです。
When I check it on the net, it seems that a method to reduce noise by “0” output from GPIO 25 with DAC is effective.

setup() の中に  In setup ()

dacWrite(25,0); を入れます。  Insert dacWrite (25,0);

結果 Result

かなり音が小さくなりまう。でもまだ鳥のさえずりのようなノイズが残っています。
The sound is quite small. But there is still noise like a bird's song.



この状態でさらにGPIO25をGNDにショートしたら音が完全になくなりました。
In this state, if I further shorted GPIO25 to GND, the sound completely disappeared.

でも将来はM5Stackに喋っともらいたいと思っているのであえてショートは織り込まないことにしました。
But in the future I decided to not short-circuit because I wanted M5Stack to speak.


#include <M5Stack.h>
#include <ESP32Servo.h> //ESPservo
#include <Wire.h> // I2C setting
#include <PCA9685.h> //PCA9685用ヘッダーファイル
#include "BluetoothSerial.h" //BluetoothSerial

BluetoothSerial SerialBT;

int ang0[] = {90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90};
int ang1[] = {90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90};
int ang_b[18];
char ang_c[18];
int ts=400;
int td=10;
int a[18],b[18];

// create four servo objects (ESP32servo)
Servo servo3;
Servo servo4;

//PCA9685のアドレス指定
PCA9685 pwm = PCA9685(0x40);

// Published values for SG90 servos; adjust if needed (ESP32servo)
int minUs = 700;
int maxUs = 2300;

#define SERVOMIN 150 //最小パルス幅 (GWS Micro2BBMG) (PCA9685)
#define SERVOMAX 500 //最大パルス幅 (GWS Micro2BBMG) (PCA9685)

// These are all GPIO pins on the ESP32
// Recommended pins include 2,4,12-19,21-23,25-27,32-33
//int servo1Pin = 2; //ESP32servo
//int servo2Pin = 5; //ESP32servo
int servo3Pin = 12; //ESP32servo
int servo4Pin = 13; //ESP32servo
//int servo5Pin = 16; //ESP32servo
//int servo6Pin = 17; //ESP32servo

void setup()
{
M5.begin();
dacWrite(25,0); //ノイズ対策
M5.Lcd.println("Bluetooth Now");

Serial.begin(9600);
SerialBT.begin("M5Stack"); //PC側で確認するときの名前

servo3.setPeriodHertz(50); // Standard 50hz servo (ESP32servo)
servo4.setPeriodHertz(50); // Standard 50hz servo (ESP32servo)

servo3.attach(servo3Pin, minUs, maxUs); // ESP32servo
servo4.attach(servo4Pin, minUs, maxUs); // ESP32servo

pwm.begin(); //初期設定 (アドレス0x40用) (PCA9685)
pwm.setPWMFreq(50); //PWM周期を50Hzに設定 (アドレス0x40用) (PCA9685)

}

void loop()
{
for (int j=0; j <=17 ; j++){
a[j] = ang1[j] - ang0[j];
b[j] = ang0[j];
ang0[j] = ang1[j];
}

for (int k=0; k <=td ; k++){

// ESP32servo

servo3.write(a[0]*k/td+b[0]);
servo4.write(a[1]*k/td+b[1]);

// PCA9685
servo_write(0,a[2]*k/td+b[2]);
servo_write(1,a[3]*k/td+b[3]);
servo_write(2,a[4]*k/td+b[4]);
servo_write(3,a[5]*k/td+b[5]);
servo_write(4,a[6]*k/td+b[6]);
servo_write(5,a[7]*k/td+b[7]);
servo_write(6,a[8]*k/td+b[8]);
servo_write(7,a[9]*k/td+b[9]);
servo_write(8,a[10]*k/td+b[10]);
servo_write(9,a[11]*k/td+b[11]);
servo_write(10,a[12]*k/td+b[12]);
servo_write(11,a[13]*k/td+b[13]);
servo_write(12,a[14]*k/td+b[14]);
servo_write(13,a[15]*k/td+b[15]);
servo_write(14,a[16]*k/td+b[16]);
servo_write(15,a[17]*k/td+b[17]);

delay(ts/td);
}

if(SerialBT.available()){
for (int i=0; i <=17; i++){
rs_gets_3c(ang_c);
ang_b[i] = atoi(ang_c);
if ((ang_b[i] > 0) && (ang_b[i] <=180))
{
M5.Lcd.print(ang_b[i]);
M5.Lcd.print(",");
ang0[i] = ang1[i];
ang1[i] = ang_b[i];
}
}
M5.Lcd.println("");
}

delay(500);
}

void servo_write(int ch, int ang){ //動かすサーボチャンネルと角度を指定
ang = map(ang, 0, 180, SERVOMIN, SERVOMAX); //角度(0~180)をPWMのパルス幅(150~500)に変換
pwm.setPWM(ch, 0, ang);
}

void rs_gets_3c(char gtc[4])
{
char gc;
int i;

sprintf(gtc," ");
for( i = 0 ; i < 4 ; i++ )
{
gc = SerialBT.read();
if (gc == ',')
break;
else
gtc[i] = gc;
}
}

コメント

コメントの投稿

非公開コメント

プロフィール

RoboTakao

Author:RoboTakao
みなさんご訪問ありがとうございます。ロボット作りたいけどお小遣いそんなにないし、簡単でローコストでロボットを作るための私のプロジェクトを紹介します。

ウェブサイトもありますのでそちらもよろしくお願いします。
http://robotakao.jp/