質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

Q&A

解決済

2回答

614閲覧

ArduinoDUEで7セグディスプレイ付き正弦波発生装置を作ろうとしたところ、アナログ出力チャンネルにノイズが発生してしまいます。

_kimura_

総合スコア14

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

0グッド

0クリップ

投稿2019/04/02 06:44

前提・実現したいこと

Arduino DUE を使用し3桁7セグLEDに周波数を表示する正弦波発生装置を作ろうとしています。

発生している問題・エラーメッセージ

GitHubにて配布されていた周波数測定用のコードをサイトの"clone or download"でzip形式にてダウンロードし、あらかじめ作成していたタクトスイッチで
制御を行う7セグLED表示機能つきの正弦波発生プログラムと組み合わせてみました。しかし7セグLEDからは周波数が表示されずランダムな数字が表示されオシロスコープで装置の出力を調べてみたところアナログ出力チャンネルから非連続型のシグナルが発生していることが分かりました。

装置を稼働させている様子を写したものです。
リンク内容

Arduino DUEのDACチャンネルの出力をオシロスコープで測定したものです。 本来は正弦波の滑らかな曲線が出るはずなのですが・・・
リンク内容

該当のソースコード

Arduino

1#include <FreqPeriodDue.h> 2 3#include "Waveforms.h" 4 5#define oneHzSample 1000000/maxSamplesNum 6#define DATA 11 7#define LATCH 10 8#define CLOCK 9 9 10// 0b11111110 DP 11// 0b11111101 A 12// 0b11111011 B 13// 0b11110111 C 14// 0b11101111 D 15// 0b11011111 E 16// 0b10111111 F 17// 0b01111111 G 18 19static const int num[] { 20 0b10000001, //ZERO 21 0b11110011, //ONE 22 0b01001001, //TWO 23 0b01100001, //THREE 24 0b00110011, //FOUR 25 0b00100101, //FIVE 26 0b00000101, //SIX 27 0b11110001, //SEVEN 28 0b00000001, //EIGHT 29 0b00100001, //NINE 30 0b10000001, //ZERO 31 32 0b11110010, //ONE DOT 33 0b01001000, //TWO DOT 34 0b01100000, //THREE DOT 35 0b00110010, //FOUR DOT 36 0b00100100, //FIVE DOT 37 0b00000100, //SIX DOT 38 0b11110000, //SEVEN DOT 39 0b00000000, //EIGHT DOT 40 0b00100000, //NINE DOT 41}; 42 43int count; 44int digits[] = {4, 3, 2}; 45int LEDdigit[] = {0, 0, 0}; //storage for digits to be displayed 46int LEDdecimal[] = {0, 0, 0}; //storage for decimal indicators 47byte scanDigit = 0; //tells which digit to display 48unsigned int start; //changed from int to unsigned int 49unsigned int timer; //changed from int to unsigned int 50unsigned int scanTimer; //timer for display scanning 51unsigned int spreod = 50; 52//int interval = 5000; 53int interval = 100; //update the display once each second 54int blinkingtime = 10; 55int del = 10;int i = 0; 56double startmicros; 57volatile int wave1 = 0; 58int lfrq; 59long int pp; 60int periodPin = 25; 61int frequency = 40000; 62const int plusbuttonPin = 53; 63const int minusbuttonPin = 52; 64int buttonStateplus = 0; 65int buttonStateminus = 0; 66unsigned int bmillis; 67 68 69void setup() 70{ 71 Serial.begin(115200); 72 FreqPeriod::begin(periodPin); 73 startPWM(frequency, PIOC, PIO_PERIPH_B, PIO_PC23, PIO_DEFAULT, 6); 74 pinMode(DATA, OUTPUT); 75 pinMode(LATCH, OUTPUT); 76 pinMode(CLOCK, OUTPUT); 77 pinMode(2, OUTPUT); 78 pinMode(3, OUTPUT); 79 pinMode(4, OUTPUT); 80 pinMode(12, OUTPUT); 81 pinMode(DAC0,OUTPUT); 82 pinMode(plusbuttonPin,INPUT_PULLUP); 83 pinMode(minusbuttonPin,INPUT_PULLUP); 84 timer = millis(); //start time for the timer 85 scanTimer = millis(); //start the display scan timer 86 bmillis = millis(); 87} 88 89void loop() 90{ 91 pp = FreqPeriod::getPeriod(); 92 if (pp){ 93 lfrq= 42000000 / pp; 94 } 95 start = millis(); 96 97 if ((start - scanTimer) >= del) //digit scanning timer 98 { 99 scanTimer = start; //reset the timer 100 scanDigit++; //display the next digit 101 if (scanDigit >= 3) { 102 scanDigit = 0; 103 } 104 digit(scanDigit, LEDdigit[scanDigit], LEDdecimal[scanDigit]); 105 } 106 107 //while (millis() - start < interval) //this will loop on the code constantly for the duration of interval 108 if ((start - timer) >= interval) //this will execute the code once when interval in reached 109 { 110 timer = start; //reset the timer 111 LEDdigit[0] = (lfrq / 100) % 10; 112 LEDdigit[1] = (lfrq / 10) % 10; 113 LEDdigit[2] = (lfrq % 10) ; 114 } 115 sineWave(); 116 attachInterrupt(52,button,CHANGE); 117 attachInterrupt(53,button,CHANGE); 118} 119 120void digit(int d, int n, int DP) 121{ //turn all digits off, digit states are HIGH 122 for (int i = 0; i < 3; i++) digitalWrite(digits[i], LOW); //changed from HIGH to LOW to disable the digits 123 digitalWrite(LATCH, LOW); //add 128 for decimal point 124 shiftOut(DATA, CLOCK, MSBFIRST, num[n]); 125 digitalWrite(LATCH, HIGH); //change display pattern 126 digitalWrite(digits[d], HIGH); //changed from LOW to HIGH here //turn digit on, digit state LOW 127} 128 129void sineWave() { 130 spreod = constrain(spreod, 50, 100); 131 if (micros() - startmicros >= spreod) 132 { 133 startmicros = micros(); 134 analogWrite(DAC0, waveformsTable[wave1][i]); // write the selected waveform on DAC0 135 136 i++; 137 if(i == maxSamplesNum) // Reset the counter to repeat the wave 138 i = 0; 139 startmicros = micros(); 140 } 141} 142 143void startPWM(uint32_t frequency, Pio* port, EPioType pinType, uint32_t pin, uint32_t pinConfig, uint32_t pwmChannel) 144{ 145 uint32_t rc = frequency * 2; 146 pmc_set_writeprotect(false); 147 pmc_enable_periph_clk(PWM_INTERFACE_ID); 148 //Set clock A to frequency in hz. 149 PWMC_ConfigureClocks(rc, 0, VARIANT_MCK); 150 //Changes the port and pin over to the requested peripheral. 151 PIO_Configure(port, pinType, pin, pinConfig); 152 //Set prescaler (PWM_CMR_CPRE_CLKA), alignment (0) and polarity (0). 153 PWMC_ConfigureChannel(PWM_INTERFACE, pwmChannel, PWM_CMR_CPRE_CLKA, 0, 0); 154 //Set period to 1MHz divided by the desired frequency. 155 PWMC_SetPeriod(PWM_INTERFACE, pwmChannel, 2); 156 //Set duty cycle to half of the period. 157 PWMC_SetDutyCycle(PWM_INTERFACE, pwmChannel, 1); //50% high, 50% low 158 PWMC_EnableChannel(PWM_INTERFACE, pwmChannel); 159} 160 161void button() 162{ 163 if (millis() - bmillis >50) 164 { 165 bmillis = millis(); 166 buttonStateplus = digitalRead(plusbuttonPin); 167 if (buttonStateplus == LOW){ 168 spreod = spreod+1; 169 } 170 buttonStateminus = digitalRead(minusbuttonPin); 171 if (buttonStateminus == LOW){ 172 spreod = spreod-1; 173 } 174 } 175} 176

<FreqPeriodDue.h>

Arduino

1/* 2 FreqPeriodDue.h 3 4 Based loosely on the FreqPeriod library from: 5 FreqPeriod.h - Library for a Frequency Measurement c. 6 Created by Martin Nawrath, KHM Lab3, June. 2010 7 Released into the public domain. 8*/ 9 10#ifndef FreqPeriod_h 11#define FreqPeriod_h 12 13#include "Arduino.h" 14 15//#define FR_USE_TC3 16#define FR_USE_TC4 17//#define FR_USE_TC5 18 19#if defined(FR_USE_TC3) //Timer clock 3 20 #define FR_USE_TC_IRQ TC3_IRQn 21 #define FR_USE_TC TC1 22 #define FR_USE_CH 0 23 #define FR_TIMER_INTR_NAME TC3_Handler 24#elif defined(FR_USE_TC4) //Timer clock 4 25 #define FR_USE_TC_IRQ TC4_IRQn 26 #define FR_USE_TC TC1 27 #define FR_USE_CH 1 28 #define FR_TIMER_INTR_NAME TC4_Handler 29#elif defined(FR_USE_TC5) //Timer clock 5 30 #define FR_USE_TC_IRQ TC5_IRQn 31 #define FR_USE_TC TC1 32 #define FR_USE_CH 2 33 #define FR_TIMER_INTR_NAME TC5_Handler 34#endif 35 36namespace FreqPeriod { 37 38 39extern volatile unsigned char f_capt; 40extern volatile unsigned long capta; 41extern volatile unsigned long captd; 42extern volatile unsigned int ocnt; 43 44 void FreqPulse(); 45 void begin(int periodPin); 46 unsigned long getPeriod(); 47} 48 49#endif

"Waveforms.h"

Arduino

1#ifndef _Waveforms_h_ 2#define _Waveforms_h_ 3 4#define maxWaveform 4 5#define maxSamplesNum 120 6 7static int waveformsTable[maxWaveform][maxSamplesNum] = { 8 // Sin wave 9 { 10 0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1, 11 0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4, 12 0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc, 13 0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f, 14 0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a, 15 0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a, 16 0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d, 17 0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a, 18 0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2, 19 0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf, 20 0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4, 21 0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794 22 } 23 , 24 25}; 26 27#endif m

ダウンロードしたArduino DUE用の周波数測定用コードのリンクです。
リンク内容
正弦波発生プログラムはArduino Forumのこちらのリンクをもとに作成しました。
リンク内容

試したこと

メインソースコードの

Arduino

1 pp = FreqPeriod::getPeriod(); 2 if (pp){ 3 lfrq= 42000000 / pp; 4 }

を、関数startPWMの中に移動させてみると7セグLEDディスプレイのランダムな数値表示から"000"という表示に変わってしまいました。

補足情報(FW/ツールのバージョンなど)

Arduino DUEの書き込みのためにボードマネージャにてArduino SAM Boards バージン1.6.12をダウンロードしています。
また、FreqPeriodDue.hのコンパイルのためにはGitHubのソースコードをZIP形式でダウンロードしarduino IDEのライブラリのインクルードにてZIP形式で導入する必要があります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

おそらく、割り込みか出力ピンがバッティングしてるんだろうけど、
以下確認してみよう

・7セグ表示を止めて、正弦波ユニットだけを動かせてきちんと出力されるのか
・7セグ表示のコモンラインの切り替えだけ実行させる(表示はしない)で、正弦波は出力されるか
・実際に7セグ表示させて正弦波出力はどうなるか

と、段階を踏んで確認してみる。ダメになったところにバグがあるので、回路図、コード含めて修正していこう


なんかコードを見てたらダメダメですね

analogWrite(DAC0, waveformsTable[wave1][i]); // write the selected waveform on DAC0

ここの変数iですが、他の場所でも使ってますね。
それは想定している動作なんでしょうか

#その他のところまで読んでらんない

投稿2019/04/02 07:15

編集2019/04/02 07:56
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwanote

2019/04/02 10:35

sineWava内のiはグローバル変数ですけどdigitのiはローカルでは?
_kimura_

2019/04/02 11:08

アドバイスありがとうございます。 とりあえず正弦波関数で使用している変数をiからkに変更してみました。 アドバイスしていただいた他の関数とのバッティングの可能性についての検証を今度オシロスコープを使える機会にしていこうと思います。
guest

0

自己解決

アナログ出力チャンネルからのノイズの原因はソースコードのコピーミスでした。
本来あるはずだった

Arduino

1 analogWriteResolution(12);

を入れ忘れたのが原因です。
今回の修正でノイズ発生がなくなりました。

まだタクトスイッチを10回押さないと周波数が変化しなかったり時折、装置の出力が一時的に停止する現象があるのでまた質問させていただくかも知れません。

アドバイスしていただいた皆様、ありがとうございます。

投稿2019/04/03 09:28

_kimura_

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問