48時間以内の記事は で表示されます
Re: 続続続続続ーPWM
またいっぱいになりました。
> 21行目 次の上げ下げは500マイクロ
それは、次の「ワイパーの」上げ下げは500usあける、という事でクロックの事ではありません。その前の1usはそれでいいです。
つまり、命令が入って、実行される=次のワイパーを繋ぎ→前のワイパーを切る、のにそれぐらいかかるから開けてくれ、という事でしょう。
No.1542の図で、オペアンプの電源になぜかコンデンサが付いていますけど?
> 21行目 次の上げ下げは500マイクロ
それは、次の「ワイパーの」上げ下げは500usあける、という事でクロックの事ではありません。その前の1usはそれでいいです。
つまり、命令が入って、実行される=次のワイパーを繋ぎ→前のワイパーを切る、のにそれぐらいかかるから開けてくれ、という事でしょう。
No.1542の図で、オペアンプの電源になぜかコンデンサが付いていますけど?
Re: 続続続続続ーPWM
デジタルでの取得も決して難しいものでは無いですよ。
MABOさんはちょっと難しく考えすぎでは?
下記程度でアナログよりもちゃんと読み取れると思います。
#include <xc.h>
#define inc LATB3
#define ud LATA3
#define mach RB4
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
//外部変数
char x9c_val;//ワイパ位置
//デバイス初期化関数
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0;
}
//U/D_up関数
void x9c_up(void) {
int ud = 1;
int inc = 0;
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
//U/Ddown関数
void x9c_down(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
//メイン関数
void main() {
OPTION_REGbits.nWPUEN = 0;
OSCCON = 0b0111001;
PORTA = 0x00;
PORTB = 0x08;
ANSELA = 0b00000000;
ANSELB = 0b00000000;
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00010000;
T1CON=0x31;//タイマー1を1/8で回す
※Mach周波数100~500Hz程度想定。→8000~40000カウント
x9c_init();
TMR1L=TMR1H=0;//タイマリセット
unsigned int p=0,d=0;
while(1) {
while(mach==0) {
if(TMR1H>250)<停止(x9c_down;)>;//250はテキトウ
}
p=(TMR1H<<8) | TMR1L;//周期記録
TMR1L=TMR1H=0;//タイマリセット
if(P>○○) { //100Hz@40000カウントなら39000とか。
target=100.0*d/p;
if(target>x9c_val)x9c_up();
else if(target<x9c_val) x9c_down();
}
}
while(RB4==1);
d=(TMR1H<<8) | TMR1L;//HIGHの時間記録
}
}
ちょっとNo.1543はスパイクが大きいような気もしますけど、
私の予定?では添付図のように周波数に合わせてwhileをまわして4点、もしくは8点を取得する、
という考えなので、多少の事はデジタルフィルタで誤魔化せます。
MABOさんはちょっと難しく考えすぎでは?
下記程度でアナログよりもちゃんと読み取れると思います。
#include <xc.h>
#define inc LATB3
#define ud LATA3
#define mach RB4
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
//外部変数
char x9c_val;//ワイパ位置
//デバイス初期化関数
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0;
}
//U/D_up関数
void x9c_up(void) {
int ud = 1;
int inc = 0;
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
//U/Ddown関数
void x9c_down(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
//メイン関数
void main() {
OPTION_REGbits.nWPUEN = 0;
OSCCON = 0b0111001;
PORTA = 0x00;
PORTB = 0x08;
ANSELA = 0b00000000;
ANSELB = 0b00000000;
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00010000;
T1CON=0x31;//タイマー1を1/8で回す
※Mach周波数100~500Hz程度想定。→8000~40000カウント
x9c_init();
TMR1L=TMR1H=0;//タイマリセット
unsigned int p=0,d=0;
while(1) {
while(mach==0) {
if(TMR1H>250)<停止(x9c_down;)>;//250はテキトウ
}
p=(TMR1H<<8) | TMR1L;//周期記録
TMR1L=TMR1H=0;//タイマリセット
if(P>○○) { //100Hz@40000カウントなら39000とか。
target=100.0*d/p;
if(target>x9c_val)x9c_up();
else if(target<x9c_val) x9c_down();
}
}
while(RB4==1);
d=(TMR1H<<8) | TMR1L;//HIGHの時間記録
}
}
ちょっとNo.1543はスパイクが大きいような気もしますけど、
私の予定?では添付図のように周波数に合わせてwhileをまわして4点、もしくは8点を取得する、
という考えなので、多少の事はデジタルフィルタで誤魔化せます。
Re: 続続続続続ーPWM
猛牛ロックさん、レス有り難うございます。
オペアンプに付けたバイパスコンデンサーです。ローパスフィルターとは役目が異なります。
必要性は 、教科書的な配慮です。
今回はコーセルだったか?
ちゃんとした電源なので、パスコンデンサーが実際必要かわ知りません。
オペアンプを高周波ノイズから守るそうです。安全側に付けます。
この先、デジタル可変抵抗とつないで、スピンドルモーターを上手く回せるか、不安です。
念の為、オペアンプのゲインを5vまで上げられるようにした方が良いでしょうか?
やったことわないので不確かですが。
ローパスフィルターに戻ります。
maboさんが参考にしてローパスフィルターを付けた実験をしオシロの写真を見せてくれました。矩形波が三角になっていました。
波形が心配です。
-****
maboさん
先達者のように、リップル対応のプログラムを頑張って作って下さい。
オペアンプに付けたバイパスコンデンサーです。ローパスフィルターとは役目が異なります。
必要性は 、教科書的な配慮です。
今回はコーセルだったか?
ちゃんとした電源なので、パスコンデンサーが実際必要かわ知りません。
オペアンプを高周波ノイズから守るそうです。安全側に付けます。
この先、デジタル可変抵抗とつないで、スピンドルモーターを上手く回せるか、不安です。
念の為、オペアンプのゲインを5vまで上げられるようにした方が良いでしょうか?
やったことわないので不確かですが。
ローパスフィルターに戻ります。
maboさんが参考にしてローパスフィルターを付けた実験をしオシロの写真を見せてくれました。矩形波が三角になっていました。
波形が心配です。
-****
maboさん
先達者のように、リップル対応のプログラムを頑張って作って下さい。
Re: 続続続続続ーPWM
猛牛ロックさん、自分の書き込みの差し換えました。。
すみません。
波形の乱れを4回のサンプルから平均値をとるから大丈夫と云いたいのですね?
理解
でも、プログラム変更するの?!
ジェジェ
前のプログラムで駄目?
すみません。
波形の乱れを4回のサンプルから平均値をとるから大丈夫と云いたいのですね?
理解
でも、プログラム変更するの?!
ジェジェ
前のプログラムで駄目?
Re: 続続続続続ーPWM
フィルターを通して読み取る方法は、元々、
・4つのサンプルから平均を取る
・1つしかワイパーを上下させない、
という2つの対策をしています。
なので、多少の乱れは大丈夫だと思っています。
もう少し…と思ったらサンプルを8個にすれば大丈夫でしょう。
ほぼ平均化されて乱れは出ないと思います。
> 前のプログラムで駄目?
この3行です。
adc[(++num)&3] = adconv();
for (char i = 0; i < 4; i++)target += adc[i];
target /= 40.93;
・4つのサンプルから平均を取る
・1つしかワイパーを上下させない、
という2つの対策をしています。
なので、多少の乱れは大丈夫だと思っています。
もう少し…と思ったらサンプルを8個にすれば大丈夫でしょう。
ほぼ平均化されて乱れは出ないと思います。
> 前のプログラムで駄目?
この3行です。
adc[(++num)&3] = adconv();
for (char i = 0; i < 4; i++)target += adc[i];
target /= 40.93;
Re: 続続続続続ーPWM
変更点を整理すると 下記の通りでしょうか?
記
39 static unsigned int adc[8] = {0};
42 adc[(++num)&7] = adconv();
43for (char i = 0; i < 8; i++)target += adc[i];
44 target /= 81.84;
記
39 static unsigned int adc[8] = {0};
42 adc[(++num)&7] = adconv();
43for (char i = 0; i < 8; i++)target += adc[i];
44 target /= 81.84;
Re: 続続続続続ーPWM
猛牛ロックさん,TRさん,こんばんは。
猛牛ロックさん,レスありがとうございます。
デジタルの読み取り難しく感じるの,割り込み等が,入って来るからだと思います。
未だに,設定が面倒なのです。
その都度,参考書と首っ引きです。
それから,デジタルの読み取りのプログラムありがとうございます。
後で,試してみます。
基本周波数を変換しても,思った結果が得られないので,
使ってるPWMのコントローラーの特性も関係あるのかな,
なんて思い始めました。
MACHからのPWMのDUTY比がRPMとどんな関係なのか,
興味がでてきましたので,のんびり,MACHのDUTY比でも計ってみようかなと思います。
TRさん,はかどりますね。
いろいろあっても,トータルとしてまとめ上げてしまうので,
TRさんもすごいな,と思います。
猛牛ロックさん,レスありがとうございます。
デジタルの読み取り難しく感じるの,割り込み等が,入って来るからだと思います。
未だに,設定が面倒なのです。
その都度,参考書と首っ引きです。
それから,デジタルの読み取りのプログラムありがとうございます。
後で,試してみます。
基本周波数を変換しても,思った結果が得られないので,
使ってるPWMのコントローラーの特性も関係あるのかな,
なんて思い始めました。
MACHからのPWMのDUTY比がRPMとどんな関係なのか,
興味がでてきましたので,のんびり,MACHのDUTY比でも計ってみようかなと思います。
TRさん,はかどりますね。
いろいろあっても,トータルとしてまとめ上げてしまうので,
TRさんもすごいな,と思います。
Re: 続続続続続ーPWM
> TRさん
そうです。8個ならそんな感じです。
でも重要な事はMACHのPWM周期とサンプリングレートの関係です。
その波形に対していいバランスでサンプルを取る事です。
> MABOさん
今現在、どんなプログラムで試しているのかは判りませんけど、
表の記事上の最新ではMACHの周波数1kHz=1000us周期にたいして、サンプリング周期は100usです。
なので、それだとサンプリング数が10でMACHからのPWMのDUTYを判断しています。
そして、サンプリング周期の整数倍が周波数になるので、うねりを持つような結果になると思います。
例えば、DUTY比が12%だとしたら、完全にPCとPICの周波数が動機すれば10%か20%のどちらかになるでしょうけど、
別のオシレータで動いていますから多少のずれが生じます。つまり、数十回?10%が続き、その後にその4倍の長さで
20%が続きます。
また、適当な割合で10%と20%が混ざるならMACHも対応してくれるかもしれないですけど、そうした動きでは難しいと思います。
せめて、30程度はサンプル数をとって、割合を算出する必要があると思います。
私がその方法を取るなら、MACHからのPWMは50Hz=200サンプルとかにすると思います。
なので、PWMの出力が来ないとの判断、つまり、タイマー0の周期はもっと遅くしてからMACHを試した方が良い、と言った次第です。
※テストの途中で停止命令が入り込むと結果の判断がより難しくなります。
そうです。8個ならそんな感じです。
でも重要な事はMACHのPWM周期とサンプリングレートの関係です。
その波形に対していいバランスでサンプルを取る事です。
> MABOさん
今現在、どんなプログラムで試しているのかは判りませんけど、
表の記事上の最新ではMACHの周波数1kHz=1000us周期にたいして、サンプリング周期は100usです。
なので、それだとサンプリング数が10でMACHからのPWMのDUTYを判断しています。
そして、サンプリング周期の整数倍が周波数になるので、うねりを持つような結果になると思います。
例えば、DUTY比が12%だとしたら、完全にPCとPICの周波数が動機すれば10%か20%のどちらかになるでしょうけど、
別のオシレータで動いていますから多少のずれが生じます。つまり、数十回?10%が続き、その後にその4倍の長さで
20%が続きます。
また、適当な割合で10%と20%が混ざるならMACHも対応してくれるかもしれないですけど、そうした動きでは難しいと思います。
せめて、30程度はサンプル数をとって、割合を算出する必要があると思います。
私がその方法を取るなら、MACHからのPWMは50Hz=200サンプルとかにすると思います。
なので、PWMの出力が来ないとの判断、つまり、タイマー0の周期はもっと遅くしてからMACHを試した方が良い、と言った次第です。
※テストの途中で停止命令が入り込むと結果の判断がより難しくなります。
Re: 続続続続続ーPWM
間違った場所に投降したので、削除し、新たに本来の場所に投降します。
**************
スンピンドル制御に必要なPWM基本周波数って、本来はどれほど必要なんだろうか?
まず、これをはっきりと、ですね。
カーネルスピードは、↓ を見て薄っすらと分かりました。
https://microsoftwindowsblogger.blogspot.com/2010/07/losing-steps-in-mach3-kernel-speed.html
分解能100とすれば(***欄より推測)、PWM基本周波数の100倍がカーネルスピードなんですね。
***
先達者のコメ抜粋
・例えば、カーネル周波数が35KHzの場合にPWM周波数を1KHzにすると階調は35段階だ。
****
で、
下の先達者は、PWM基本周波数が、15KHzと設定しようとした。
だが、MACHのカーネルスピードは、MAX100kHz
MAX100,000Hz<15000Hz×100倍=1500,000
となり、PWM信号を制御できなくなった。 そこで、
ローパスフィルターってことになったんですね。
先達は
題目:CNC3020のスピンドル制御
先達者のURL
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
抵抗:22k
コンデンサ:10μ
カットオフ周波数?
答え
0.7Hz
感想
こんなに低い周波数から、ゲインさせてしまって、良く上手くいったものだと思いました。
猛牛ロックさんへ
8個サンプリングにしたら、効果大です。
ほぼ、ちらつきなくなりました。
**************
スンピンドル制御に必要なPWM基本周波数って、本来はどれほど必要なんだろうか?
まず、これをはっきりと、ですね。
カーネルスピードは、↓ を見て薄っすらと分かりました。
https://microsoftwindowsblogger.blogspot.com/2010/07/losing-steps-in-mach3-kernel-speed.html
分解能100とすれば(***欄より推測)、PWM基本周波数の100倍がカーネルスピードなんですね。
***
先達者のコメ抜粋
・例えば、カーネル周波数が35KHzの場合にPWM周波数を1KHzにすると階調は35段階だ。
****
で、
下の先達者は、PWM基本周波数が、15KHzと設定しようとした。
だが、MACHのカーネルスピードは、MAX100kHz
MAX100,000Hz<15000Hz×100倍=1500,000
となり、PWM信号を制御できなくなった。 そこで、
ローパスフィルターってことになったんですね。
先達は
題目:CNC3020のスピンドル制御
先達者のURL
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
抵抗:22k
コンデンサ:10μ
カットオフ周波数?
答え
0.7Hz
感想
こんなに低い周波数から、ゲインさせてしまって、良く上手くいったものだと思いました。
猛牛ロックさんへ
8個サンプリングにしたら、効果大です。
ほぼ、ちらつきなくなりました。
Re: 続続続続続ーPWM
カーネル周波数とPWM周波数の考え方は合っていますけど、参考サイトの見方に関しては
・MACHからの出力(PICへの入力)
・モータへの出力
がごちゃ混ぜになっています。
また、都合のいいように話を持って行き過ぎです。
音の聞こえない15kHz(実際には15.6kHz)にしようとした(目的)のはモータへの出力の周波数です。
で、、目的の周波数(15kHz)でMACHから出力させて、モータに直接繋いだのでは2,3段階の諧調しか得られない。
なので直結での静音化(MACHから15kHz出力)は無理なので、「PICを使って周波数変換しよう」、という事です。
※この人のスピンドルのドライバはPWMの信号を入れるタイプ(=それが普通)です。
MACHからのPWMの周波数の記載はありませんから、参考サイトにある「250Hz」と「10mSの移動平均フィルタ」
から推測するしかありません。多分100〜250Hz程度だと思います。フィルタは、その周波数に応じて用意します。
**************
Machの周波数に対して、分割数で割ったものを最後の_delay_ms();の部分の周期にしてください。
Machから100HzのPWMが来て、分割数が8なら1.25msです。
その場合は,
__delay_us(1250);
になります。(けれどもデバイスの仕様上、500us以下は動作は保証されません。)
多分、現在の設定はPWMの周波数がもっと高くて、ランダムな場所になっているのだと思います。
それはそれで、8個ぐらい取れば平均値に近づきますから悪くないです。
※一番悪いのは同期して、波の同じ部分を取得してしまう事です。
・MACHからの出力(PICへの入力)
・モータへの出力
がごちゃ混ぜになっています。
また、都合のいいように話を持って行き過ぎです。
音の聞こえない15kHz(実際には15.6kHz)にしようとした(目的)のはモータへの出力の周波数です。
で、、目的の周波数(15kHz)でMACHから出力させて、モータに直接繋いだのでは2,3段階の諧調しか得られない。
なので直結での静音化(MACHから15kHz出力)は無理なので、「PICを使って周波数変換しよう」、という事です。
※この人のスピンドルのドライバはPWMの信号を入れるタイプ(=それが普通)です。
MACHからのPWMの周波数の記載はありませんから、参考サイトにある「250Hz」と「10mSの移動平均フィルタ」
から推測するしかありません。多分100〜250Hz程度だと思います。フィルタは、その周波数に応じて用意します。
**************
Machの周波数に対して、分割数で割ったものを最後の_delay_ms();の部分の周期にしてください。
Machから100HzのPWMが来て、分割数が8なら1.25msです。
その場合は,
__delay_us(1250);
になります。(けれどもデバイスの仕様上、500us以下は動作は保証されません。)
多分、現在の設定はPWMの周波数がもっと高くて、ランダムな場所になっているのだと思います。
それはそれで、8個ぐらい取れば平均値に近づきますから悪くないです。
※一番悪いのは同期して、波の同じ部分を取得してしまう事です。
Re: 続続続続続ーPWM
15kHzは、ローパス後の電圧をPWMに変換後の周波数でしたね。
了解、
でも、PWM基本周波数のローパスのカットオフ周波数が0.7Hzでいいものだろうか?
猛牛ロックさんの推測↓
多分100〜250Hz程度だ
PWM基本周波数100〜250Hzなのに、カットオフ0.7Hzが適正なのか気になります。
実際は。どうなのか?
>__delay_us(1250);
これは、
10 __delay_us(500);を(1250)に変更ですね。 了解しました。
でも、
>Machから100HzのPWMが来て、分割数が8なら1.25msです。
これの算出方法は、
100Hz/8回サンプリング で、OK?
デジタル可変抵抗のスタート位置を決める式でしたよね、
この辺の訳を教えてください。
お願いします。
でも、カーネルSpeedとPWM基本周波数の関係が分かってよかったです。
6/5 14:30追記
非反転オペアンプですが、
落とし穴が分かりました。
DC12Vをオペアンプの電源に印可しないと駄目です。
了解、
でも、PWM基本周波数のローパスのカットオフ周波数が0.7Hzでいいものだろうか?
猛牛ロックさんの推測↓
多分100〜250Hz程度だ
PWM基本周波数100〜250Hzなのに、カットオフ0.7Hzが適正なのか気になります。
実際は。どうなのか?
>__delay_us(1250);
これは、
10 __delay_us(500);を(1250)に変更ですね。 了解しました。
でも、
>Machから100HzのPWMが来て、分割数が8なら1.25msです。
これの算出方法は、
100Hz/8回サンプリング で、OK?
デジタル可変抵抗のスタート位置を決める式でしたよね、
この辺の訳を教えてください。
お願いします。
でも、カーネルSpeedとPWM基本周波数の関係が分かってよかったです。
6/5 14:30追記
非反転オペアンプですが、
落とし穴が分かりました。
DC12Vをオペアンプの電源に印可しないと駄目です。
Re: 続続続続続ーPWM
No.1553の添付図を見てください。(元はMABOさんの信号です。)
で、その図の縦線は読み取り点のことです。1つの波(周期)にたいして、4つサンプルを取っているものです。
MachのPWM周期を100Hz(=0.01s周期)に設定すれば、4サンプルなら2.5msですし、8サンプル(8分割)なら1.25msになります。
単純にPWM周期をサンプル個数で割っているだけです。
※その図で、ある1つの縦線の部分で8つサンプルを取ったら、全てがその縦線の値になってしまいますし、4つ分ずらした間隔で8サンプル習得しても
全て波の同じ部分を取得している事になるので良くないです。
> MABOさん
タイマー1を回さなくてもPWMは取得できます。主要部だけですけど
while(1){
unsigned long count_h=0,count_l=0;
while(mach);//HIGHの間、閉じ込める
while(!mach);//LOWの間、閉じ込める(次のHIGHの先頭を出すため)
while(mach){
count_h++;
if(count_h>@@@@)SetPWM(0);//ダミー?
}
while(!mach){
count_l++;
if(count_l>@@@@)SetPWM(0);
}
int duty=1023.0*count_h/(count_h+count_l);
SetPWM(duty);
// __delay_ms(1);
}
HIGH信号の時間を数えてLOW信号の時間を数えるだけです。
勿論、他に割り込みを使っていればカウント値が狂いますからその場合は
if(周期がこの間にあったら)・・・
といった処理が必要になります。この方法なら分母は数百や数千にはなるでしょうから、100usのサンプリングより正確なものが求まります。
で、その図の縦線は読み取り点のことです。1つの波(周期)にたいして、4つサンプルを取っているものです。
MachのPWM周期を100Hz(=0.01s周期)に設定すれば、4サンプルなら2.5msですし、8サンプル(8分割)なら1.25msになります。
単純にPWM周期をサンプル個数で割っているだけです。
※その図で、ある1つの縦線の部分で8つサンプルを取ったら、全てがその縦線の値になってしまいますし、4つ分ずらした間隔で8サンプル習得しても
全て波の同じ部分を取得している事になるので良くないです。
> MABOさん
タイマー1を回さなくてもPWMは取得できます。主要部だけですけど
while(1){
unsigned long count_h=0,count_l=0;
while(mach);//HIGHの間、閉じ込める
while(!mach);//LOWの間、閉じ込める(次のHIGHの先頭を出すため)
while(mach){
count_h++;
if(count_h>@@@@)SetPWM(0);//ダミー?
}
while(!mach){
count_l++;
if(count_l>@@@@)SetPWM(0);
}
int duty=1023.0*count_h/(count_h+count_l);
SetPWM(duty);
// __delay_ms(1);
}
HIGH信号の時間を数えてLOW信号の時間を数えるだけです。
勿論、他に割り込みを使っていればカウント値が狂いますからその場合は
if(周期がこの間にあったら)・・・
といった処理が必要になります。この方法なら分母は数百や数千にはなるでしょうから、100usのサンプリングより正確なものが求まります。
Re: 続続続続続ーPWM
猛牛ロックさん 有難うございます。
了解です。
聞いて良かったです。
Kanel SppedとPWM基本周波数も分かったし、
これで応用が利くようになりました。
同じ電圧にしなくてもいいかもしれませんが、
念には念を。
**********
maboさんへ
若しよかったら、オシロをお持ちでしょうから、
ローパスフィルター有り無しで、波形を比べて頂けませんか?
すでにご存じなら、教えてください。
御手隙の時で結構です。
それから、
非反転オペアンプの電源は、PICの電源と分けました。
これによって、PICのUDやINK端子に掛かる電圧と同じにできるようになりました。
一応、DC12V電源なしでもデジタル可変抵抗が動作すれば、12Vは外します。
了解です。
聞いて良かったです。
Kanel SppedとPWM基本周波数も分かったし、
これで応用が利くようになりました。
同じ電圧にしなくてもいいかもしれませんが、
念には念を。
**********
maboさんへ
若しよかったら、オシロをお持ちでしょうから、
ローパスフィルター有り無しで、波形を比べて頂けませんか?
すでにご存じなら、教えてください。
御手隙の時で結構です。
それから、
非反転オペアンプの電源は、PICの電源と分けました。
これによって、PICのUDやINK端子に掛かる電圧と同じにできるようになりました。
一応、DC12V電源なしでもデジタル可変抵抗が動作すれば、12Vは外します。
Re: 続続続続続ーPWM
No.1566の添付図を見ましたけど、オペアンプは何のために使っているのでしょうか?
私はx9cのRwからオペアンプの+に入れて、outからスピンドルへと繋ぐのかと思っていました。
私はx9cのRwからオペアンプの+に入れて、outからスピンドルへと繋ぐのかと思っていました。
Re: 続続続続続ーPWM
ML4のスピンドルモーター制御基板は、資料も何もないので弄れません。
なので、素人には理解できないと思います。
そこで、期待を込めて
ML4のスピード制御には、可変抵抗(DC5V印可の1KΩ)が使われています。
モーターの大きさから、どうも、ACサーボモーターのようです。
推測ですが、三菱のACサーボモーターもアンプ側にスピードコントロール用にアナログの可変抵抗をつけます。
ML4のと同じだろうと思いました。
デジタル可変抵抗と置き換えたら、どうだろうかと思った次第です。
追記
x9cのデータシートに下記の説明がありました。
動作電圧でしょうか?
もしそうなら。
記
U/D input HIGH voltage min2V Mxa Vcc+1
なので、素人には理解できないと思います。
そこで、期待を込めて
ML4のスピード制御には、可変抵抗(DC5V印可の1KΩ)が使われています。
モーターの大きさから、どうも、ACサーボモーターのようです。
推測ですが、三菱のACサーボモーターもアンプ側にスピードコントロール用にアナログの可変抵抗をつけます。
ML4のと同じだろうと思いました。
デジタル可変抵抗と置き換えたら、どうだろうかと思った次第です。
追記
x9cのデータシートに下記の説明がありました。
動作電圧でしょうか?
もしそうなら。
記
U/D input HIGH voltage min2V Mxa Vcc+1
Re: 続続続続続ーPWM
猛牛ロックさん,TRさん,こんばんは。
なんかこの掲示板も内容がすごいことになってるな,
なんて,びっくりしてます。
なかなかついていけません。
猛牛ロックさん,サンプリング等のプログラムありがとう
ございます。
また,詳しい解説もすみません。
なんとなく理解できそうな気もしますが,難しいです。
TRさん,いろいろお疲れ様です。
ところで,今日は,ちょっと前に帰ってきたのですが,
MACHからのPWMのDUTY比をオシロで見てみました。
スケールで目視での確認ですので,おおざっぱです
下記の設定で,
MACHカーネル 25000hz
PWM基本周波数 100hz
MaxSpeed 9000rpm
設定rpm DUTY比
1000 10%
2000 20%
3000 32%
4000 44%
5000 54%
6000 68%
7000 78%
8000 90%
9000 98%
と,ほぼ比例でしたが,私が使ったPWMコントロールのドライバーは,
入力DUTY比 RPM
4% 1283
6% 2256
7% 3049
11% 4061
14% 5003
19% 6125
25% 7000
36% 8015
69% 9000
比例どころか,DUTY比 14% のPWMの入力で,
モーター能力のほぼ半分の回転数になってします。
他のPWM入力のコントローラーはわかりませんが,
こんなもんなんでしょうかね。使ってるFET等の性能
なんかも影響してるんでしょうかね。
別のものも試してみたくなりました。
なんかこの掲示板も内容がすごいことになってるな,
なんて,びっくりしてます。
なかなかついていけません。
猛牛ロックさん,サンプリング等のプログラムありがとう
ございます。
また,詳しい解説もすみません。
なんとなく理解できそうな気もしますが,難しいです。
TRさん,いろいろお疲れ様です。
ところで,今日は,ちょっと前に帰ってきたのですが,
MACHからのPWMのDUTY比をオシロで見てみました。
スケールで目視での確認ですので,おおざっぱです
下記の設定で,
MACHカーネル 25000hz
PWM基本周波数 100hz
MaxSpeed 9000rpm
設定rpm DUTY比
1000 10%
2000 20%
3000 32%
4000 44%
5000 54%
6000 68%
7000 78%
8000 90%
9000 98%
と,ほぼ比例でしたが,私が使ったPWMコントロールのドライバーは,
入力DUTY比 RPM
4% 1283
6% 2256
7% 3049
11% 4061
14% 5003
19% 6125
25% 7000
36% 8015
69% 9000
比例どころか,DUTY比 14% のPWMの入力で,
モーター能力のほぼ半分の回転数になってします。
他のPWM入力のコントローラーはわかりませんが,
こんなもんなんでしょうかね。使ってるFET等の性能
なんかも影響してるんでしょうかね。
別のものも試してみたくなりました。
Re: 続続続続続ーPWM
見落とししているかもしれないので再度の書きこです。
**********
maboさんへ
若しよかったら、オシロをお持ちでしょうから、
ローパスフィルター有り無しで、波形を比べて頂けませんか?
すでにご存じなら、教えてください。
御手隙の時で結構です。
**********
maboさんへ
若しよかったら、オシロをお持ちでしょうから、
ローパスフィルター有り無しで、波形を比べて頂けませんか?
すでにご存じなら、教えてください。
御手隙の時で結構です。
Re: 続続続続続ーPWM
Re: 続続続続続ーPWM
TRさん,済みませんでした。
今気がつきました。
>ローパスフィルター有り無しで、波形を比べて頂けませんか?
これ,MACHからの信号でいいですか?
No1533がローパスフィルター通したPWMの信号です。
外すと,きれいな,PWMの信号になります。
今気がつきました。
>ローパスフィルター有り無しで、波形を比べて頂けませんか?
これ,MACHからの信号でいいですか?
No1533がローパスフィルター通したPWMの信号です。
外すと,きれいな,PWMの信号になります。
Re: 続続続続続ーPWM
maboさんへ、
仮にですが、
カットオフ周波数を変えるために、コンデンサとRを替えてみたらどうですか?
カットオフ15000Hzに。
自分は、手計算が面倒なので、↓のツールを使います。
15kHzなら、0.1マイク、15kΩ
sim.okawa-denshi.jp/CRtool.php
仮にですが、
カットオフ周波数を変えるために、コンデンサとRを替えてみたらどうですか?
カットオフ15000Hzに。
自分は、手計算が面倒なので、↓のツールを使います。
15kHzなら、0.1マイク、15kΩ
sim.okawa-denshi.jp/CRtool.php
PWM信号
maboさんこんばんは。
ポケモンの方進んでいますか??
大分前のことで恐縮ですが、
若し覚えていたら、コメントを下さい。
maboさんのブログの記事です。
−−−SPINDLEのPWM制御−−−2015-02-15 Sun
この件です。
本文の最後の方に
以下のことを記載しています。
***
階調のことを考えると、MACHの基本周波数を低めにして、
コンバートの回路でもつくる必要があるんでしょうね。
***
この件について、外国の方が、PIC16F88を使っています。
英語なので、顛末は分かりません。
http://www.buildlog.net/cnc_laser/mach_laser_power.html
で、なんですが、
−−−SPINDLEのPWM制御−−−2015-02-13 Fri
この記事の中では、PWM信号を取り出したと記述されていますが、
そのピンは、ポート1の14ピンですか?
ポート1の14ピンは、出力ピンですよね?
ということは、スピンドルモーターを制御するFETを使ってある場合
このFETのゲートに、ポート1の14ピンをつなげば、
後は、MACH3にGコードを入れて、そのGコードで、
スピンドルモーターをON,OFF、回転数制御できるようになるのでしょうか???
写真は、スピンドルモーター制御の必要と思われるMACH3の写真です。
この話に必要と思われましたので付けました。
宜しくお願いします。
Re: PWM信号
TRさん,ご無沙汰です。
半分仕事の延長で手伝っているHPのリニューアルのため,
なれないHTMLのタグ等いじってて,
自分のブログの時間とれませんでした。
という訳で,おたずねの件ですが,
過去のことで,記憶が曖昧な部分もありますので,
違ってるかもしれませんので,そのときはすみません。
>ポート1の14ピンは、出力ピンですよね
ですが多分そうだと思います。
2015-02-11の私の記事のコメントで,
『今日、SS→S○Cさんコントローラー→14ピンからの信号をオシロで確認することができました。
PWMの信号を出せるようです。ただ、実際の運用にあたっては、いくつか配慮が必要だと思います。』
と記載してますので,多分あってるかと思います。
>このFETのゲートに、ポート1の14ピンをつなげば、
>後は、MACH3にGコードを入れて、そのGコードで、
>スピンドルモーターをON,OFF、回転数制御できるようになるのでしょうか???
この辺は実際の運用をしてないので,なんともですが,
基本的に可能だと思います。
(FETを介しての,PWM制御をお考えなんですね。)
yusa さんのHPには,たしか,ACサーボを,
http://yusa.c.ooco.jp/mini_cnc/acsrabo.html
MACHからPWM制御した記事があったと思います。
ただ,実際に運用するには,いくつか配慮が必要かと思
います。
以前,MISTのコントロールの記事で,SECさんの基盤の,
14からの出力を論理IC経由で出力して,100VのON-OFFを
しましたが,
間に,フォットカプラー等いれて,100Vととは,
遮断した方がベストかな,と思ったりしてます。
以前,DCモーターをMACHから制御しようと,
購入した回路がありました。
http://projectdress.jp/newhp/posts/ditem13.html
実際の運用にいたらず,しまい込んでいますので,
暇みて,また,再開してみようかなと思います。
追伸
ポケモンのおもちゃは完成,でも,わざわざこれを使う必要もなく,スイッチの短絡ですましてます。
半分仕事の延長で手伝っているHPのリニューアルのため,
なれないHTMLのタグ等いじってて,
自分のブログの時間とれませんでした。
という訳で,おたずねの件ですが,
過去のことで,記憶が曖昧な部分もありますので,
違ってるかもしれませんので,そのときはすみません。
>ポート1の14ピンは、出力ピンですよね
ですが多分そうだと思います。
2015-02-11の私の記事のコメントで,
『今日、SS→S○Cさんコントローラー→14ピンからの信号をオシロで確認することができました。
PWMの信号を出せるようです。ただ、実際の運用にあたっては、いくつか配慮が必要だと思います。』
と記載してますので,多分あってるかと思います。
>このFETのゲートに、ポート1の14ピンをつなげば、
>後は、MACH3にGコードを入れて、そのGコードで、
>スピンドルモーターをON,OFF、回転数制御できるようになるのでしょうか???
この辺は実際の運用をしてないので,なんともですが,
基本的に可能だと思います。
(FETを介しての,PWM制御をお考えなんですね。)
yusa さんのHPには,たしか,ACサーボを,
http://yusa.c.ooco.jp/mini_cnc/acsrabo.html
MACHからPWM制御した記事があったと思います。
ただ,実際に運用するには,いくつか配慮が必要かと思
います。
以前,MISTのコントロールの記事で,SECさんの基盤の,
14からの出力を論理IC経由で出力して,100VのON-OFFを
しましたが,
間に,フォットカプラー等いれて,100Vととは,
遮断した方がベストかな,と思ったりしてます。
以前,DCモーターをMACHから制御しようと,
購入した回路がありました。
http://projectdress.jp/newhp/posts/ditem13.html
実際の運用にいたらず,しまい込んでいますので,
暇みて,また,再開してみようかなと思います。
追伸
ポケモンのおもちゃは完成,でも,わざわざこれを使う必要もなく,スイッチの短絡ですましてます。
Re: PWM信号
maboさん、レスありがとうございます。
>(FETを介しての,PWM制御をお考えなんですね。)
そうです。
自分には、SEC基板からのDC5VのHi/Loの信号をつかって、
モーターに電流を流す方法しか知りません。
>間に,フォットカプラー等いれて,100Vととは,
遮断した方がベストかな,と思ったりしてます。
SEC基板〜フォトカプラ(または、ソリッドステートリレーかな?)〜AC100VのON/OFF
という感じでしょうか?
Sable−2015用スピンドルコントローラーPCタイプ
このコントローラーは、SEC基板を使う人には不要なのでしょうか?
ま〜、Sable−2015用スピンドルモーターなのでしょうから、
DC24V以上は無理でしょうけど。
忙しいところありがとうございます。
実際、自分の場合、フライス盤のML4を使っているので、
ML4の制御基板を理解できれば、改造して、SEC基板につないで、MACH3で制御できるのでしょうけど、、、。
ML4の制御基板を理解できないでしょうから、、、(苦笑
ML4の制御基板を外して、ML4のモーターだけを、単にMACH3から制御できる仕掛け ↓ を作れたらいいのですが。
SEC基板〜フォトカプラ(または、ソリッドステートリレーかな?)〜?この辺から謎??〜ML4のモーター(これが、エアコンのAC200Vなんですよ)
>(FETを介しての,PWM制御をお考えなんですね。)
そうです。
自分には、SEC基板からのDC5VのHi/Loの信号をつかって、
モーターに電流を流す方法しか知りません。
>間に,フォットカプラー等いれて,100Vととは,
遮断した方がベストかな,と思ったりしてます。
SEC基板〜フォトカプラ(または、ソリッドステートリレーかな?)〜AC100VのON/OFF
という感じでしょうか?
Sable−2015用スピンドルコントローラーPCタイプ
このコントローラーは、SEC基板を使う人には不要なのでしょうか?
ま〜、Sable−2015用スピンドルモーターなのでしょうから、
DC24V以上は無理でしょうけど。
忙しいところありがとうございます。
実際、自分の場合、フライス盤のML4を使っているので、
ML4の制御基板を理解できれば、改造して、SEC基板につないで、MACH3で制御できるのでしょうけど、、、。
ML4の制御基板を理解できないでしょうから、、、(苦笑
ML4の制御基板を外して、ML4のモーターだけを、単にMACH3から制御できる仕掛け ↓ を作れたらいいのですが。
SEC基板〜フォトカプラ(または、ソリッドステートリレーかな?)〜?この辺から謎??〜ML4のモーター(これが、エアコンのAC200Vなんですよ)
Re: PWM信号
TRさん,こんばんは。
あまりお役にたてなくてすみません。
不明な点多いのですが,多分,
「SEC基板→フォトカプラ→SSR→制御機器」
みたいにした方が,SEC基板もPC安全のような気がしますが,
MISTの制御では,
「SEC基板→論理IC→SSR→制御機器」
でやりました。
下記のコントローラーは,
http://projectdress.jp/newhp/posts/ditem13.html
Sable−2015用ですが,
Sable−2015の制御基板を通さないで,
パラレルポートの信号を横取りする形で取り出して,
直接24VのDCモーターをPWMで制御するようです。
ですので,SEC基板には関係なく使えると思いますが,
あまり大きな出力(W)のモーターには無理かなと思います。
以前,パラレルポートからの信号を横取りする形で,
RCのブラシレスモーターを制御するものを購入したことも
あります。
写真のものです。
これも,CNCの制御基板に関係なく使えますが,
RCモーターですね。
TRさんのCNCのスピンドル,AC200Vでしたか。
ACだとすぐ思いつくのが,インバーターの使用でしょうかね。
インバーターを使うと,
SEC基板→「リレー」→「インバーター」→「スピンドル」
で,制御できそうな気がします。
https://jisaku-koubou.com/archives/2674
に,インバーターを使ったスピンドルのコントロールの記事があります。
あまりお役にたてなくてすみません。
不明な点多いのですが,多分,
「SEC基板→フォトカプラ→SSR→制御機器」
みたいにした方が,SEC基板もPC安全のような気がしますが,
MISTの制御では,
「SEC基板→論理IC→SSR→制御機器」
でやりました。
下記のコントローラーは,
http://projectdress.jp/newhp/posts/ditem13.html
Sable−2015用ですが,
Sable−2015の制御基板を通さないで,
パラレルポートの信号を横取りする形で取り出して,
直接24VのDCモーターをPWMで制御するようです。
ですので,SEC基板には関係なく使えると思いますが,
あまり大きな出力(W)のモーターには無理かなと思います。
以前,パラレルポートからの信号を横取りする形で,
RCのブラシレスモーターを制御するものを購入したことも
あります。
写真のものです。
これも,CNCの制御基板に関係なく使えますが,
RCモーターですね。
TRさんのCNCのスピンドル,AC200Vでしたか。
ACだとすぐ思いつくのが,インバーターの使用でしょうかね。
インバーターを使うと,
SEC基板→「リレー」→「インバーター」→「スピンドル」
で,制御できそうな気がします。
https://jisaku-koubou.com/archives/2674
に,インバーターを使ったスピンドルのコントロールの記事があります。
Re: PWM信号
maboさん、ありがとうございます。
インバーターっていうのがあるのですね!
これなら行けそうですね。
ML4のモーターは単相3線式のAC200V 2.2Kwというやつです。
アマゾンに合いそうなのが売っていました。 これなら行けそうですね!
富士電機 FRN2.2C2S-7J 単相200V 2.2kw
https://www.amazon.co.jp/dp/B076GMJHS4/ref=sspa_dk_detail_4?psc=1&pd_rd_i=B076GMJHS4&pd_rd_w=QQlgS&pf_rd_p=
6f76bf7b-14cf-4ddf-acee-6d90d5cf8e2e&pd_rd_wg=XjhyM&pf_rd_r=E7XM045AYMHFZ94JEX9W&pd_rd_r=853756ef-7692-11e9-8a2e-db5fc0625183
>SEC基板→「リレー」→「インバーター」→「スピンドル」
で,制御できそうな気がします。
そうですね。
汎用出力14(SEC基板のSL18)をリレーにつなぐわけですよね?
下のSEC基板は、具体に言えば、(SEC基板のSL18)ということですよね?
>SEC基板→「リレー」→「インバーター」→「スピンドル」
具体に言えば
SEC基板のSL18→「リレー」→「インバーター」→「スピンドル」
後は、MACH3の設定ですよね。
この辺がよく分かりません。
写真の左上の緑枠を14
写真右上の水色も14に設定
写真右下のSEC基板の14は赤枠の場所、こことソリッドステートリレーをつなぐ。
赤矢印の カーネルスピードというのが分かりませんね〜。???
インバーターっていうのがあるのですね!
これなら行けそうですね。
ML4のモーターは単相3線式のAC200V 2.2Kwというやつです。
アマゾンに合いそうなのが売っていました。 これなら行けそうですね!
富士電機 FRN2.2C2S-7J 単相200V 2.2kw
https://www.amazon.co.jp/dp/B076GMJHS4/ref=sspa_dk_detail_4?psc=1&pd_rd_i=B076GMJHS4&pd_rd_w=QQlgS&pf_rd_p=
6f76bf7b-14cf-4ddf-acee-6d90d5cf8e2e&pd_rd_wg=XjhyM&pf_rd_r=E7XM045AYMHFZ94JEX9W&pd_rd_r=853756ef-7692-11e9-8a2e-db5fc0625183
>SEC基板→「リレー」→「インバーター」→「スピンドル」
で,制御できそうな気がします。
そうですね。
汎用出力14(SEC基板のSL18)をリレーにつなぐわけですよね?
下のSEC基板は、具体に言えば、(SEC基板のSL18)ということですよね?
>SEC基板→「リレー」→「インバーター」→「スピンドル」
具体に言えば
SEC基板のSL18→「リレー」→「インバーター」→「スピンドル」
後は、MACH3の設定ですよね。
この辺がよく分かりません。
写真の左上の緑枠を14
写真右上の水色も14に設定
写真右下のSEC基板の14は赤枠の場所、こことソリッドステートリレーをつなぐ。
赤矢印の カーネルスピードというのが分かりませんね〜。???
Re: PWM信号
TRさん,今晩は。
ちょっと調べて見ましたが,
>単相3線式のAC200V
だとインバーターでの駆動厳しいかもです。
インバーターのほとんどが,3相出力なので,
これだと多分,動かないかもです。
TRさんのご紹介くださったインバーターも出力は,
3相200Vのようですので,使えないかも。
ネットでくぐったら,単相出力のインバーターは,
少ないとの記載もあります。
出力が単相の3線だと,多分,100Vと200Vに使えると思いますが。
単相の3線は,通常家庭への引き込みがそうなっていて,
結線の仕方で,100Vと200Vとれるようになってます。
ちょっと調べて見る必要ありかもですね。
それとカーネルスピードですが,
私もよく分からないところで,
CPUのクロックかな,と思ったこともありますけど,
はっきり説明できません。
リナックス等では,カーネルという言葉はよくできてき,
カーネルとは,リナックスの根幹をなスプログラムので,
もしかすると,MACHの根幹をなすプログラムの動作スピードのことかな,
なんて考えたりしてますけど,断言はできません。
カーネルスピードをいじると,ステッピングモーターの設定も
変える必要もある,との記載も見受けられます。
また,レーザーCNCでカーネルスピードをいじると影響があるの記載もありました。
https://blogs.yahoo.co.jp/tomtchi/9669785.html
というので,?です。
ちょっと調べて見ましたが,
>単相3線式のAC200V
だとインバーターでの駆動厳しいかもです。
インバーターのほとんどが,3相出力なので,
これだと多分,動かないかもです。
TRさんのご紹介くださったインバーターも出力は,
3相200Vのようですので,使えないかも。
ネットでくぐったら,単相出力のインバーターは,
少ないとの記載もあります。
出力が単相の3線だと,多分,100Vと200Vに使えると思いますが。
単相の3線は,通常家庭への引き込みがそうなっていて,
結線の仕方で,100Vと200Vとれるようになってます。
ちょっと調べて見る必要ありかもですね。
それとカーネルスピードですが,
私もよく分からないところで,
CPUのクロックかな,と思ったこともありますけど,
はっきり説明できません。
リナックス等では,カーネルという言葉はよくできてき,
カーネルとは,リナックスの根幹をなスプログラムので,
もしかすると,MACHの根幹をなすプログラムの動作スピードのことかな,
なんて考えたりしてますけど,断言はできません。
カーネルスピードをいじると,ステッピングモーターの設定も
変える必要もある,との記載も見受けられます。
また,レーザーCNCでカーネルスピードをいじると影響があるの記載もありました。
https://blogs.yahoo.co.jp/tomtchi/9669785.html
というので,?です。
Re: PWM信号
maboさん、おはようございます。
インバーターの方は、製造メーカーに聞きながら確認したいと思います。
ML4のモーターは、こんなところでもつまずいてしまうとは。
とりあえず、以下のようにつないで、テスターの電圧を確認します。
SEC基盤のPORT1の1番ピンのSIGNAL端子→テスター棒(赤)
SEC基板のPORT1の1番ピンのGND→テスター棒(黒)
MACH3の設定方法はPWM発生させる場合
※maboさんブログより
−−−MACHによる回転数表示(2)−−−
2016-06-08 Wed
この記事中にある、 Usb SmootStepper v1.7fe Config の設定で,
Spindle IndexPrescaleの項目です。
この通りに設定!!
また、以下のように設定!!
写真左下
カーネルスピードはデフォルト
写真左上
Motor OutputのSpindle
写真右上
Spindle SetupのRelay Controlと Motor Control
写真右下
Output Signals
以上の通りやってみて、SEC基板の1番ピンの電圧があるかどうか見ます。
インバーターの方は、製造メーカーに聞きながら確認したいと思います。
ML4のモーターは、こんなところでもつまずいてしまうとは。
とりあえず、以下のようにつないで、テスターの電圧を確認します。
SEC基盤のPORT1の1番ピンのSIGNAL端子→テスター棒(赤)
SEC基板のPORT1の1番ピンのGND→テスター棒(黒)
MACH3の設定方法はPWM発生させる場合
※maboさんブログより
−−−MACHによる回転数表示(2)−−−
2016-06-08 Wed
この記事中にある、 Usb SmootStepper v1.7fe Config の設定で,
Spindle IndexPrescaleの項目です。
この通りに設定!!
また、以下のように設定!!
写真左下
カーネルスピードはデフォルト
写真左上
Motor OutputのSpindle
写真右上
Spindle SetupのRelay Controlと Motor Control
写真右下
Output Signals
以上の通りやってみて、SEC基板の1番ピンの電圧があるかどうか見ます。
Re: PWM信号
Re: PWM信号
TRさん,こんばんは。
TRさん,すみません,
>Spindle IndexPrescaleの項目です。
の設定は,外部ので計測した回転数をMACHで表示するための設定で,
PWMの出力には,直接は関係ないと思います。
http://www.buildlog.net/cnc_laser/mach_laser_power.html
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
に書いてある項目の設定で大丈夫だと思います。
No1459の写真で,Disable Spidle Relays にチェックを
いれると,
下部の設定は,いらないと思います。
それから,Motor Output の設定で,Spindleの項目は,
PWMを出力させる,ポートとピン番号を入れると思いますので,
◯ECさんの基盤のNo14の汎用出力で確認するには,
Step Pin# 14
Dir Pin# 1
Step Port 1
Dir Port 1
の設定になると思います。それから,PWMの基本周波数等の設定
ありますけど,確認するだけなら,
100位でいいと思います。
それから,もう一カ所,Pully Selectionの設定もあるようおですが,テストだけなら大丈夫かも。
http://projectdress.jp/Sable-2015_Motor_Controller_for_PC_manual.pdf
のMACHの設定が参考になると思います。
ただ,どうなんでしょうか,テスターで確認だと難しいかも。
抵抗介して,LEDランプ等接続すると,ごく低速回転だと,
LEDの点滅で,確認できるかもですね。
実際運用するとなると,やはりPWMの基本周波数を変換するPICを介さないと,だめでしょうね。
TRさん,すみません,
>Spindle IndexPrescaleの項目です。
の設定は,外部ので計測した回転数をMACHで表示するための設定で,
PWMの出力には,直接は関係ないと思います。
http://www.buildlog.net/cnc_laser/mach_laser_power.html
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
に書いてある項目の設定で大丈夫だと思います。
No1459の写真で,Disable Spidle Relays にチェックを
いれると,
下部の設定は,いらないと思います。
それから,Motor Output の設定で,Spindleの項目は,
PWMを出力させる,ポートとピン番号を入れると思いますので,
◯ECさんの基盤のNo14の汎用出力で確認するには,
Step Pin# 14
Dir Pin# 1
Step Port 1
Dir Port 1
の設定になると思います。それから,PWMの基本周波数等の設定
ありますけど,確認するだけなら,
100位でいいと思います。
それから,もう一カ所,Pully Selectionの設定もあるようおですが,テストだけなら大丈夫かも。
http://projectdress.jp/Sable-2015_Motor_Controller_for_PC_manual.pdf
のMACHの設定が参考になると思います。
ただ,どうなんでしょうか,テスターで確認だと難しいかも。
抵抗介して,LEDランプ等接続すると,ごく低速回転だと,
LEDの点滅で,確認できるかもですね。
実際運用するとなると,やはりPWMの基本周波数を変換するPICを介さないと,だめでしょうね。
Re: PWM信号
maboさんへ
> どうなんでしょうか,テスターで確認だと難しいかも。
抵抗介して,LEDランプ等接続すると,ごく低速回転だと,
LEDの点滅で,確認できるかもですね。
思い出しました。
自分は、クーラントポンプのために、SEC基板(ポート2 1番端子)にPICをつないでいます。
そこで、さっそく、クーラントポンプが回るかテストをしました。
条件
・SEC基板や基板からクーラントポンプなどの配線はそのままです。
MACH3の設定を、写真のようにしました。
でも、ポート2の1番ピンには、電圧が発生していないようで、ポンプは全く回らず、モーターからもウイーンという音も
なし。電圧のモニター用に設けたLEDも光っていません。 ポート2の1番ピンには電圧がないようです。
ダメでした。
ただ、写真右下 Spindle CW F5をクリックしたら、黄色い枠が点灯したので、
MACH3の画面は、動作しています。
maboさんの記事を見てもう一度やりましたが
ダメでした。どうしてでしょうか?
> どうなんでしょうか,テスターで確認だと難しいかも。
抵抗介して,LEDランプ等接続すると,ごく低速回転だと,
LEDの点滅で,確認できるかもですね。
思い出しました。
自分は、クーラントポンプのために、SEC基板(ポート2 1番端子)にPICをつないでいます。
そこで、さっそく、クーラントポンプが回るかテストをしました。
条件
・SEC基板や基板からクーラントポンプなどの配線はそのままです。
MACH3の設定を、写真のようにしました。
でも、ポート2の1番ピンには、電圧が発生していないようで、ポンプは全く回らず、モーターからもウイーンという音も
なし。電圧のモニター用に設けたLEDも光っていません。 ポート2の1番ピンには電圧がないようです。
ダメでした。
ただ、写真右下 Spindle CW F5をクリックしたら、黄色い枠が点灯したので、
MACH3の画面は、動作しています。
maboさんの記事を見てもう一度やりましたが
ダメでした。どうしてでしょうか?
Re: PWM信号
TRさん,おはようございます。
よく分からない点もありますが,
ポートの2をお使いになったということでしょうか。
多分,ポート2をお使いの場合は,
◯ECさんの基板からではなく,
SSのポート2の該当pinに結線しないとだめだと思います。
◯ECさんの基板には,SSのポート1の結線しかしてありませんので。
私もちょと,また,いろいろいじってみます。
よく分からない点もありますが,
ポートの2をお使いになったということでしょうか。
多分,ポート2をお使いの場合は,
◯ECさんの基板からではなく,
SSのポート2の該当pinに結線しないとだめだと思います。
◯ECさんの基板には,SSのポート1の結線しかしてありませんので。
私もちょと,また,いろいろいじってみます。
Re: PWM信号
Re: PWM信号
ポート2の1番ピンから、同ポート2の14番ピンに
差し替えても、PWMの出力が出ました。
ここまでわかっただけでも良かったです。
maboさんありがとう。
しかし、この先は、金との相談です。
差し替えても、PWMの出力が出ました。
ここまでわかっただけでも良かったです。
maboさんありがとう。
しかし、この先は、金との相談です。
Re: PWM信号
maboさん、もう一点お願いします。
SEC基板の事です。
汎用出力14を使う場合、SEC基板の抵抗をプルアップからプルダウンにしないと
電源が入ったと同時に、モーターが動いてしまいます。
汎用出力1番の時もそうでした。
その時は、SEC基板のR1をプルダウンに変更しました。
で、今回は、汎用出力の14です。
これに対応する抵抗は、R14でよろしいでしょうか?
下のURLを見たら、SEC基板と思われる図面がありました。
タイトルは、「【パラレル・インターフェース】 CNCインターフェース基板・・・カレントダウン」
ここにありました。
http://sec589.blog50.fc2.com/blog-category-7.html
SEC基板の事です。
汎用出力14を使う場合、SEC基板の抵抗をプルアップからプルダウンにしないと
電源が入ったと同時に、モーターが動いてしまいます。
汎用出力1番の時もそうでした。
その時は、SEC基板のR1をプルダウンに変更しました。
で、今回は、汎用出力の14です。
これに対応する抵抗は、R14でよろしいでしょうか?
下のURLを見たら、SEC基板と思われる図面がありました。
タイトルは、「【パラレル・インターフェース】 CNCインターフェース基板・・・カレントダウン」
ここにありました。
http://sec589.blog50.fc2.com/blog-category-7.html
Re: PWM信号
TRさん,こんばんは。
回路図はまともには読めないので?なのですが,
もしかして,TRさんは,◯ECさんの拡張基板も
お使いではありませんでしたか。
となると,ちょっと不明です。
以前,TRさんがプルダウンに変更したような問題を,
間に論理IC入れることで解決しました。
本来のICの使い方ではないのでしょうが,その記事は,
私のSSR BY SSの記事に書いてます。
NOR回路を使ってます。
私は汎用出力の14でコントロールをして,
そのための電源を汎用出力の12から取ったようです。(記憶があいまいです。)
◯ECさんの基板の汎用出力の14の出力がLOWの信号と
同じく◯ECさんの基板のアースのLOWのNORをとって,
出力をHIGHTにしました。
ただ,◯ECさんの基板の電源がOFFになると,論理ICは
HIGHTを出力するようになりますので,
◯ECさんの基板から電源を取ることで,論理ICの電源を落とし,
結果的に論理ICからの出力をLOWにしてます。
回路図はまともには読めないので?なのですが,
もしかして,TRさんは,◯ECさんの拡張基板も
お使いではありませんでしたか。
となると,ちょっと不明です。
以前,TRさんがプルダウンに変更したような問題を,
間に論理IC入れることで解決しました。
本来のICの使い方ではないのでしょうが,その記事は,
私のSSR BY SSの記事に書いてます。
NOR回路を使ってます。
私は汎用出力の14でコントロールをして,
そのための電源を汎用出力の12から取ったようです。(記憶があいまいです。)
◯ECさんの基板の汎用出力の14の出力がLOWの信号と
同じく◯ECさんの基板のアースのLOWのNORをとって,
出力をHIGHTにしました。
ただ,◯ECさんの基板の電源がOFFになると,論理ICは
HIGHTを出力するようになりますので,
◯ECさんの基板から電源を取ることで,論理ICの電源を落とし,
結果的に論理ICからの出力をLOWにしてます。
Re: PWM信号
maboさん、こんにちは。
>◯ECさんの拡張基板も
お使いではありませんでしたか。
良くわからないのですが、SECさんから、2枚買って、Smoothステッパーに2枚をつないでいます。
拡張基板ってどんなものなのですか?
今更ですみません。
>論理IC入れることで解決しました。
論理ICを調べて分かりました。
NORの場合、論理ICに入る信号を反転させるようですね。
なので、SEC基板の信号を逆にするわけか。
これなら行けそうですね。
ご紹介の記事を見てそのことが分かりました。
SSR by SSの記事です。
SECさんの回路図を見て少しわかりましたが、パラレルポートの25Pの信号を
論理IC(74HC540N)で受けているようですね。
SECさんの記事にそのことがあります。 ↓
※※※※ 〜
題目 → 【パラレル・インターフェース】 CNCインターフェース基板・・・カレントダウン
記載内容 ↓
CNCインターフェース基板の
D−SUB25PとモータードライバーへのインターフェースICや汎用入出力IC
此処にバッファーを設けています
ノンインバータ(非反転)です
〜※※※※
で、なんですが、
maboさんが、使ったSN54HC02が、協立エレショップや秋月電子にも売っていません。
NOR回路ICとして、協立エレショップに74HC4078がありました、maboさんの使った
SN54HC02の代替品として使えますか?
http://eleshop.jp/shop/g/gF1G12K/
7:51追記
電源ONと同時に、出力端子がONになるのかようやく分かりました。
SECさんの論理ICです。
出力端子1の流れになります。
1番出力にONにならなくても、論理ICのA1につながっているプルアップ抵抗には、
電源がつながっているので、電源ONと同時にA1もHIになるからです。
A1がHIになれば、
SECさんのICは、正論理だから、
流れを整理すると ↓
電源ON → A1 ON → Y1 ON
※ 追記にかかる写真もアップしました。
>◯ECさんの拡張基板も
お使いではありませんでしたか。
良くわからないのですが、SECさんから、2枚買って、Smoothステッパーに2枚をつないでいます。
拡張基板ってどんなものなのですか?
今更ですみません。
>論理IC入れることで解決しました。
論理ICを調べて分かりました。
NORの場合、論理ICに入る信号を反転させるようですね。
なので、SEC基板の信号を逆にするわけか。
これなら行けそうですね。
ご紹介の記事を見てそのことが分かりました。
SSR by SSの記事です。
SECさんの回路図を見て少しわかりましたが、パラレルポートの25Pの信号を
論理IC(74HC540N)で受けているようですね。
SECさんの記事にそのことがあります。 ↓
※※※※ 〜
題目 → 【パラレル・インターフェース】 CNCインターフェース基板・・・カレントダウン
記載内容 ↓
CNCインターフェース基板の
D−SUB25PとモータードライバーへのインターフェースICや汎用入出力IC
此処にバッファーを設けています
ノンインバータ(非反転)です
〜※※※※
で、なんですが、
maboさんが、使ったSN54HC02が、協立エレショップや秋月電子にも売っていません。
NOR回路ICとして、協立エレショップに74HC4078がありました、maboさんの使った
SN54HC02の代替品として使えますか?
http://eleshop.jp/shop/g/gF1G12K/
7:51追記
電源ONと同時に、出力端子がONになるのかようやく分かりました。
SECさんの論理ICです。
出力端子1の流れになります。
1番出力にONにならなくても、論理ICのA1につながっているプルアップ抵抗には、
電源がつながっているので、電源ONと同時にA1もHIになるからです。
A1がHIになれば、
SECさんのICは、正論理だから、
流れを整理すると ↓
電源ON → A1 ON → Y1 ON
※ 追記にかかる写真もアップしました。
Re: 続続続続ーPWM
件数が一杯になったので新しくしました。
> static unsigned int adc[4] = {0}; − adc[4]の意味?
別の書き方だと
static unsigned int adc[4]={0,0,0,0};
です。
ローカル変数は何も入れないと、元々その位置に書かれている数値になってしまいます。
外部変数なら何も入れなくても0に初期化されます。
> adc[(++num)&3] = adconv();
これも別の書き方なら
num=num+1;
adc[num&0b11]=adconv();
です。
num++;
if(num%4=0)num=0;
adc[num]=adconv();
でも同じです。やっている事は特に違いはありません。
毎回要素の[0]→[1]→[2]→[3]→ 番目になるように切り替えています。
で、次の行でそのADCの4つを足しています。
本体のtargetはその次の行の40.2で割る事で出るのですけど、別の変数を用意するのも面倒なので
そうしています。つまり、4つ足したときはまだ、targetはtarget値(MACHが出力しているワイパー位置)では無いです。
目標のワイパー位置がtargetで、実際のワイパー位置がx9c_valです。
目標の方が大きければupさせて、目標の方が少なければdowmさせています。
> 以下のように、adconv()関数をmain関数の後につけましたが、どうもうまくつながりません。
これはどういった意味でしょうか?コンパイルできないという事ですか?
LEDの動作については、それを考慮したものになっていません。書いてある通りにMACHからの信号→X9Cの操作というだけです。
> static unsigned int adc[4] = {0}; − adc[4]の意味?
別の書き方だと
static unsigned int adc[4]={0,0,0,0};
です。
ローカル変数は何も入れないと、元々その位置に書かれている数値になってしまいます。
外部変数なら何も入れなくても0に初期化されます。
> adc[(++num)&3] = adconv();
これも別の書き方なら
num=num+1;
adc[num&0b11]=adconv();
です。
num++;
if(num%4=0)num=0;
adc[num]=adconv();
でも同じです。やっている事は特に違いはありません。
毎回要素の[0]→[1]→[2]→[3]→ 番目になるように切り替えています。
で、次の行でそのADCの4つを足しています。
本体のtargetはその次の行の40.2で割る事で出るのですけど、別の変数を用意するのも面倒なので
そうしています。つまり、4つ足したときはまだ、targetはtarget値(MACHが出力しているワイパー位置)では無いです。
目標のワイパー位置がtargetで、実際のワイパー位置がx9c_valです。
目標の方が大きければupさせて、目標の方が少なければdowmさせています。
> 以下のように、adconv()関数をmain関数の後につけましたが、どうもうまくつながりません。
これはどういった意味でしょうか?コンパイルできないという事ですか?
LEDの動作については、それを考慮したものになっていません。書いてある通りにMACHからの信号→X9Cの操作というだけです。
Re: 続続続続ーPWM
maboさんへ、
デジタル可変抵抗ですが、自分は
データシートだと、100ワイパーtapとなっていて、最小で40Ω残るとなっている。
1タップは、10kΩ/1024/100タップ。
なので、、100で割るという考えはいいと思いますが、
最小40Ω残るとある点がちょっと気になります。
10Ω−0.4kΩを100で割る制御となるんでしょうけど。ML4に使ったら、どうなるかは、実機(ML4)で試しましょう。
No1388を頭の隅に入れておきます。
> A+=A
は,
A=A+1
と同じ意味で,表記方法が違うだけです
代入演算子というそうですね。 代入という表記がやっとわかりました。
でも、A+=A → A=A+Aとなるのでは??
LCDの使い方はまだ分かりませんが、気にはなっていました。憧れです。
今やっていることが理解できたら、と思います。 とりあえず、お気に入りに保存。
***************
猛牛ロックさんへ
自分にとって、本当の難しいと思います。 でも、慣れることと思って反復しています。
プログラムができてきましたが、INCピン(RB3)はプルダウンでよろしいでしょうか?
39〜50行目の事が薄っすらとわかってきました。でもでも、、、解釈ですが、
配列要素0番時のadocnv値を0番時のtargetに代入,
次に、1番時のadoconv値を,1番時のtargetと0番時のtargetに加算、続けて3番時、4番時とtargetを加算すると読めるが?
仮にそうであっても、
43行目が難しい、+=が代入演算子であれば、
公式A+=Bに当てはめるとA=A+Bのはず、targetを加算するという前記の内容となるのか?
**** 追記 ***
そうか分かった、for分の次に来る{}を端折ってあって、実のところ、{target+=adc[i]}なんだ、多分、であれば、そうかもしれない!
でも、コンパイルできません。
プログラムですが、以下の通り考えましたが、コンパイル不可です。
恐縮ですが、見て頂けませんでしょうか、ギブ状態です。お助け願いますm(__)m
/*RB4で電圧読み取り*/
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//
//INCピン(RB3)はプルダウン
//
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdlib.h>
#include <math.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
//外部変数
char x9c_val;//ワイパ位置
int inc;
int ud;
//デバイス初期化関数
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0;
}
//U/D_up関数
void x9c_up(void) {
int ud = 1;
int inc = 0;
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
//U/Ddown関数
void x9c_dowm(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
//メイン関数
void main() {
OPTION_REGbits.nWPUEN = 0; //内部プルアップ有効
OSCCON =
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報設定(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
//変数宣言
while (1) {
static unsigned int adc[4] = {0};
static char num = 0;
unsigned int target = 0;
adc[(++num)&3] = adconv();
for (char i = 0; i < 4; i++)target += adc[i];
target /= 40.93;
if (target > x9c_val)x9c_up();
else if (target < x9c_val)x9c_down();
_delay_ms(1);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
追記
デジタル可変抵抗につけようかと思う比反転のオペアンプです。
利得1倍にしようかと思います。
デジタル可変抵抗ですが、自分は
データシートだと、100ワイパーtapとなっていて、最小で40Ω残るとなっている。
1タップは、10kΩ/1024/100タップ。
なので、、100で割るという考えはいいと思いますが、
最小40Ω残るとある点がちょっと気になります。
10Ω−0.4kΩを100で割る制御となるんでしょうけど。ML4に使ったら、どうなるかは、実機(ML4)で試しましょう。
No1388を頭の隅に入れておきます。
> A+=A
は,
A=A+1
と同じ意味で,表記方法が違うだけです
代入演算子というそうですね。 代入という表記がやっとわかりました。
でも、A+=A → A=A+Aとなるのでは??
LCDの使い方はまだ分かりませんが、気にはなっていました。憧れです。
今やっていることが理解できたら、と思います。 とりあえず、お気に入りに保存。
***************
猛牛ロックさんへ
自分にとって、本当の難しいと思います。 でも、慣れることと思って反復しています。
プログラムができてきましたが、INCピン(RB3)はプルダウンでよろしいでしょうか?
39〜50行目の事が薄っすらとわかってきました。でもでも、、、解釈ですが、
配列要素0番時のadocnv値を0番時のtargetに代入,
次に、1番時のadoconv値を,1番時のtargetと0番時のtargetに加算、続けて3番時、4番時とtargetを加算すると読めるが?
仮にそうであっても、
43行目が難しい、+=が代入演算子であれば、
公式A+=Bに当てはめるとA=A+Bのはず、targetを加算するという前記の内容となるのか?
**** 追記 ***
そうか分かった、for分の次に来る{}を端折ってあって、実のところ、{target+=adc[i]}なんだ、多分、であれば、そうかもしれない!
でも、コンパイルできません。
プログラムですが、以下の通り考えましたが、コンパイル不可です。
恐縮ですが、見て頂けませんでしょうか、ギブ状態です。お助け願いますm(__)m
/*RB4で電圧読み取り*/
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//
//INCピン(RB3)はプルダウン
//
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdlib.h>
#include <math.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
//外部変数
char x9c_val;//ワイパ位置
int inc;
int ud;
//デバイス初期化関数
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0;
}
//U/D_up関数
void x9c_up(void) {
int ud = 1;
int inc = 0;
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
//U/Ddown関数
void x9c_dowm(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
//メイン関数
void main() {
OPTION_REGbits.nWPUEN = 0; //内部プルアップ有効
OSCCON =
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報設定(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
//変数宣言
while (1) {
static unsigned int adc[4] = {0};
static char num = 0;
unsigned int target = 0;
adc[(++num)&3] = adconv();
for (char i = 0; i < 4; i++)target += adc[i];
target /= 40.93;
if (target > x9c_val)x9c_up();
else if (target < x9c_val)x9c_down();
_delay_ms(1);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
追記
デジタル可変抵抗につけようかと思う比反転のオペアンプです。
利得1倍にしようかと思います。
Re: 続続続続ーPWM
incピンはプルする必要はありません。繋げば良いです。
もしプルするとしても、普通は通常時のH=プルアップですね。
1.
udとincの扱いが違います。これは変数では無く、LATレジスタです。
#define inc LATB3
#define ud LATA3
の2行を前半に入れてください。
そして、それに伴って、
int inc;
int ud;
のような箇所は消してください。
int ud = 1;
のような箇所も
ud=1;
です。(intは消してください) 実際は
LATA3=1;
をしたいわけです。
2.
> while (1) {
の前に
x9c_init();
を入れてください。
3.
私のケアレスミスです。
x9c_dowm → x9c_down
_delay_ms → __delay_ms
これでコンパイルは通ると思います。
※付いていても問題はありませんけど、私の方は
#include <stdlib.h>
#include <math.h>
は必要ありません。
*****************************
adc[(++num)&3] = adconv();
は↑で説明した通りです。
毎回来た時にnumが1増えますからそれと&3を取って、0〜3の範囲にしています。
来るたびにadc[1]→adc[2]→と変わります。
繰り替えすので、一番古い位置に新しいADC値を入れる事になります。
for (char i = 0; i < 4; i++)target += adc[i];
は、for文を取ると
target=target+adc[0];
target=target+adc[1];
target=target+adc[2];
target=target+adc[3];
です。
実際はその上で
unsigned int target = 0;
をしていますから、ここに入る前はtargetは0になっています。なので、
target=adc[0]+adc[1]+adc[2]+adc[3];
と同じです。
もしプルするとしても、普通は通常時のH=プルアップですね。
1.
udとincの扱いが違います。これは変数では無く、LATレジスタです。
#define inc LATB3
#define ud LATA3
の2行を前半に入れてください。
そして、それに伴って、
int inc;
int ud;
のような箇所は消してください。
int ud = 1;
のような箇所も
ud=1;
です。(intは消してください) 実際は
LATA3=1;
をしたいわけです。
2.
> while (1) {
の前に
x9c_init();
を入れてください。
3.
私のケアレスミスです。
x9c_dowm → x9c_down
_delay_ms → __delay_ms
これでコンパイルは通ると思います。
※付いていても問題はありませんけど、私の方は
#include <stdlib.h>
#include <math.h>
は必要ありません。
*****************************
adc[(++num)&3] = adconv();
は↑で説明した通りです。
毎回来た時にnumが1増えますからそれと&3を取って、0〜3の範囲にしています。
来るたびにadc[1]→adc[2]→と変わります。
繰り替えすので、一番古い位置に新しいADC値を入れる事になります。
for (char i = 0; i < 4; i++)target += adc[i];
は、for文を取ると
target=target+adc[0];
target=target+adc[1];
target=target+adc[2];
target=target+adc[3];
です。
実際はその上で
unsigned int target = 0;
をしていますから、ここに入る前はtargetは0になっています。なので、
target=adc[0]+adc[1]+adc[2]+adc[3];
と同じです。
Re: 続続続続ーPWM
コンパイルできましたが、動作しません!?
RB3が点灯したままです。
これで、正常でしょうか?
RA3は、増加時でに点灯、減時に消灯、これで正常でしょうか?
RA3は、多少、ふらふらしている感じです。
具体的には、VRが停止したままだと、ONになっています。
RB3が点灯したままです。
これで、正常でしょうか?
RA3は、増加時でに点灯、減時に消灯、これで正常でしょうか?
RA3は、多少、ふらふらしている感じです。
具体的には、VRが停止したままだと、ONになっています。
Re: 続続続続ーPWM
RA3は、増加時でに点灯、減時に消灯、これで正常でしょうか?
RA3は、多少、ふらふらしている感じです。
具体的には、VRが停止したままだと、ONになっています。
プログラム中に
//INCピン(RB3)はプルダウン
の記述があったので、このピンがincピンだと思い、
#define inc LATB3
としました。
incピンは平時HIGHです。
なので、プルアップ抵抗は必要では無いし、付けるとしてもプルアップ抵抗、と言いました。
勿論、これはクロックピンに相当しますから、上げ下げする時に動きます。
なので、凡そ予定通りの動きです。
ちゃんと動いているかは実際の抵抗値で計測してください。
RA3は、多少、ふらふらしている感じです。
具体的には、VRが停止したままだと、ONになっています。
プログラム中に
//INCピン(RB3)はプルダウン
の記述があったので、このピンがincピンだと思い、
#define inc LATB3
としました。
incピンは平時HIGHです。
なので、プルアップ抵抗は必要では無いし、付けるとしてもプルアップ抵抗、と言いました。
勿論、これはクロックピンに相当しますから、上げ下げする時に動きます。
なので、凡そ予定通りの動きです。
ちゃんと動いているかは実際の抵抗値で計測してください。
Re: 続続続続ーPWM
#define inc LATB3
#define ud LATA3
void x9c_dowm(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
INCは、マニュアルでは、上方から下方へダウンしているので、
プログラムを逆にするのでは?
inc = 0; 1に変更
__delay_us(1);
inc = 1; 0に変更
追記
&3とありますが、
ビット演算子のことですか?
#define ud LATA3
void x9c_dowm(void) {
ud = 0;
inc = 0;
__delay_us(1);
inc = 1;
if (x9c_val > 0)x9c_val--;
//次の上げ下げは500us空ける
}
INCは、マニュアルでは、上方から下方へダウンしているので、
プログラムを逆にするのでは?
inc = 0; 1に変更
__delay_us(1);
inc = 1; 0に変更
追記
&3とありますが、
ビット演算子のことですか?
Re: 続続続続ーPWM
maboさん、
猛牛ロックさんへ
今回のプログラム、もっと熟読します。
で、
もう少し頑張ろうかと思います。
ADコンバートした値などを、ご紹介くださったモニターで確認することはできますか?
http://akizukidenshi.com/catalog/g/gP-00038/
猛牛ロックさんへ
今回のプログラム、もっと熟読します。
で、
もう少し頑張ろうかと思います。
ADコンバートした値などを、ご紹介くださったモニターで確認することはできますか?
http://akizukidenshi.com/catalog/g/gP-00038/
Re: 続続続続ーPWM
勿論そのLCDに表示する事も可能ですけど、
私はデバック用ならI2Cタイプをお薦めします。
使用ピンが少ないので対応し易いです。
もっと簡易的ならTM1637チップの7セグです。
https://www.amazon.co.jp/dp/B07FL5Y9ND/
でも、今の段階はまだPCが近くですよね?
そのままMPLAB Xのデバックで表示させた方が良いのではないかと思います。
**********
> INCは、マニュアルでは、上方から下方へダウンしているので、
> プログラムを逆にするのでは?
>
>
> inc = 0; 1に変更
> __delay_us(1);
> inc = 1; 0に変更
違います。変えては駄目です。ここに入る前、つまり平常時がHIGHです。
incピンを下げて、1usその状態を保って、highにして、500us待ちます。
※待つのはループの1msで実現させています。
上下を決めるのは、incを0にした瞬間のudピンの状態です。
私はデバック用ならI2Cタイプをお薦めします。
使用ピンが少ないので対応し易いです。
もっと簡易的ならTM1637チップの7セグです。
https://www.amazon.co.jp/dp/B07FL5Y9ND/
でも、今の段階はまだPCが近くですよね?
そのままMPLAB Xのデバックで表示させた方が良いのではないかと思います。
**********
> INCは、マニュアルでは、上方から下方へダウンしているので、
> プログラムを逆にするのでは?
>
>
> inc = 0; 1に変更
> __delay_us(1);
> inc = 1; 0に変更
違います。変えては駄目です。ここに入る前、つまり平常時がHIGHです。
incピンを下げて、1usその状態を保って、highにして、500us待ちます。
※待つのはループの1msで実現させています。
上下を決めるのは、incを0にした瞬間のudピンの状態です。
Re: 続続続続ーPWM
adc[(++num)&3] = adconv();
これの&3、&はビット演算子でしょうか?
教わった中で、ビットをマスク処理したときに使いました。
でも、1を返しました。
&3の3は何なのでしょうか?
KKHMF 4デジタル表示モジュールLED明るさ調節可能 時計付き
商品を見ました。
ピンの機能に、「DIOはデータ入力出力ピン,」
とありました。
これに繋ぐとどんなことができるのでしょうか?
プログラムは簡単なのでしょうか?
簡単なサイトがありますか?
+++++
今気が付いたのですが、
プログラムにCSピンを制御することが抜けています。
どうしたらよいでしょうか??
追記
3を2進数にしたら11でした。
なので、
0 0 0 1
1 1 1 1
0 0 0 1
10進数 0 1
猛牛ロックさん、凄い!!
これの&3、&はビット演算子でしょうか?
教わった中で、ビットをマスク処理したときに使いました。
でも、1を返しました。
&3の3は何なのでしょうか?
KKHMF 4デジタル表示モジュールLED明るさ調節可能 時計付き
商品を見ました。
ピンの機能に、「DIOはデータ入力出力ピン,」
とありました。
これに繋ぐとどんなことができるのでしょうか?
プログラムは簡単なのでしょうか?
簡単なサイトがありますか?
+++++
今気が付いたのですが、
プログラムにCSピンを制御することが抜けています。
どうしたらよいでしょうか??
追記
3を2進数にしたら11でした。
なので、
0 0 0 1
1 1 1 1
0 0 0 1
10進数 0 1
猛牛ロックさん、凄い!!
Re: 続続続続ーPWM
> これの&3、&はビット演算子でしょうか?
そうです。
> 教わった中で、ビットをマスク処理したときに使いました。
> でも、1を返しました。
これもマスク処理です。内容が1なので1を返したのでしょう。
次のループ時には2を返すはずです。
> &3の3は何なのでしょうか?
3は3です。0b11でも0x03でも同じです。
この場合は0b11の方が判りやすいでしょう。
つまり、下位2ビットだけ取り出しています。
> これに繋ぐとどんなことができるのでしょうか?
単なる4桁の7セグです。7セグなので主に数値しか表示できません。
特別な事はインターフェイスが2本になって、簡単に繋げられる、という事だけです。
※これを2つ使って、目標回転数(上段)と実際の回転数(下段)を表示させたらいいのでは?と思っていたものです。
実物は小さいですけどね。
> プログラムは簡単なのでしょうか?
まぁ、出来る事が簡単(数字だけ)な事だけなので、キャラクタ液晶よりかは簡単な制御(コマンド)です。
サイトに関しては検索したことが無いので判りませんけど、有名なモジュールなので山ほどあるかと思います。
そうです。
> 教わった中で、ビットをマスク処理したときに使いました。
> でも、1を返しました。
これもマスク処理です。内容が1なので1を返したのでしょう。
次のループ時には2を返すはずです。
> &3の3は何なのでしょうか?
3は3です。0b11でも0x03でも同じです。
この場合は0b11の方が判りやすいでしょう。
つまり、下位2ビットだけ取り出しています。
> これに繋ぐとどんなことができるのでしょうか?
単なる4桁の7セグです。7セグなので主に数値しか表示できません。
特別な事はインターフェイスが2本になって、簡単に繋げられる、という事だけです。
※これを2つ使って、目標回転数(上段)と実際の回転数(下段)を表示させたらいいのでは?と思っていたものです。
実物は小さいですけどね。
> プログラムは簡単なのでしょうか?
まぁ、出来る事が簡単(数字だけ)な事だけなので、キャラクタ液晶よりかは簡単な制御(コマンド)です。
サイトに関しては検索したことが無いので判りませんけど、有名なモジュールなので山ほどあるかと思います。
Re: 続続続続ーPWM
+++++
今気が付いたのですが、
プログラムにCSピンを制御することが抜けています。
どうしたらよいでしょうか??
今気が付いたのですが、
プログラムにCSピンを制御することが抜けています。
どうしたらよいでしょうか??
Re: 続続続続ーPWM
了解です。
ということは、
プログラムで
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
この記載で足りるということですか?
そうであれば、PICの入力ピンか出力ピンに繋ぐということですよね?
追記
マニュアルに拘りました。
それに、x9c103のピンも何処かに繋げておいた方が
安定するとも思いました。
その他には、GNDでしょうか?
ということは、
プログラムで
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
この記載で足りるということですか?
そうであれば、PICの入力ピンか出力ピンに繋ぐということですよね?
追記
マニュアルに拘りました。
それに、x9c103のピンも何処かに繋げておいた方が
安定するとも思いました。
その他には、GNDでしょうか?
Re: 続続続続ーPWM
Re: 続続続続ーPWM
TRさん,猛牛ロックさん,こんばんは。
********TRさんへ********
TRさん,猛牛ロックさんのプログラムで,ちょっと。
LEDで点滅の動作を確認するには,
void x9c_up(void) {
int ud = 1;
*****
int inc = 0;
*****
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
の****の部分に,__delay_ms(100);
とか,挿入すると,確認できると思います。
点滅の具合は,数値の増減で,いかようにもできるかも。
それと,
>ADコンバートした値などを、ご紹介くださったモニターで確>認することはできますか?
>http://akizukidenshi.com/catalog/g/gP-00038/
確認できます。私は,LCDで確認してます。
XIDEでも確認できるのでしょうが,面倒というか,やり方が
よく分からないとこもあるので,実機で確認してます。
猛牛ロックさんは,I2Cのものをご紹介くださってますが,
私にには,ちょっと,設定が面倒で,未だ使ってない状態です。
私が取り上げたものなら,表示のライブラリーがありますので,比較的容易にできます。
特別な設定等もありません。あるとすれば,使用するピン
を #define で指定するだけです。
それと,1542の配線図ですが,SECさんからの入力に,
抵抗とコンデンサーはないようです。
これないと,PWMがデジタルのまま入ります。
******猛牛ロックさんへ******
今日,PWMの出力に抵抗とコンデンサーを入れたのを
オシロで確認したり,ADCで取り込んだりしてみました。
22kと10μFですが,リップルとスパイク?等あるみたいでした。
フェライト入れても変化なしでした。
********TRさんへ********
TRさん,猛牛ロックさんのプログラムで,ちょっと。
LEDで点滅の動作を確認するには,
void x9c_up(void) {
int ud = 1;
*****
int inc = 0;
*****
__delay_us(1);
int inc = 1;
if (x9c_val < 99)x9c_val++;
//次の上げ下げは500us空ける
}
の****の部分に,__delay_ms(100);
とか,挿入すると,確認できると思います。
点滅の具合は,数値の増減で,いかようにもできるかも。
それと,
>ADコンバートした値などを、ご紹介くださったモニターで確>認することはできますか?
>http://akizukidenshi.com/catalog/g/gP-00038/
確認できます。私は,LCDで確認してます。
XIDEでも確認できるのでしょうが,面倒というか,やり方が
よく分からないとこもあるので,実機で確認してます。
猛牛ロックさんは,I2Cのものをご紹介くださってますが,
私にには,ちょっと,設定が面倒で,未だ使ってない状態です。
私が取り上げたものなら,表示のライブラリーがありますので,比較的容易にできます。
特別な設定等もありません。あるとすれば,使用するピン
を #define で指定するだけです。
それと,1542の配線図ですが,SECさんからの入力に,
抵抗とコンデンサーはないようです。
これないと,PWMがデジタルのまま入ります。
******猛牛ロックさんへ******
今日,PWMの出力に抵抗とコンデンサーを入れたのを
オシロで確認したり,ADCで取り込んだりしてみました。
22kと10μFですが,リップルとスパイク?等あるみたいでした。
フェライト入れても変化なしでした。
Re: 続続続続ーPWM
maboさん、こんばんは。
点滅の件、ありがとございます。
あくまでも確認用ですね。
>私が取り上げたものなら,表示のライブラリーがありますので,比較的容易にできます。
特別な設定等もありません。あるとすれば,使用するピン
を #define で指定するだけです。
AD値などを確認できるのでしょうか?
済みませんが、URLを教えてください。
ローパスフィルターを入れない理由は、
自分の場合、ML4の可変抵抗の代わりに、デジタル可変抵抗を入れ替えるので、
うまくいったら、ローパスフィルターなしで行けるかもと思いました。
maboさんの場合は、自分と違って、
maboさんの場合は、
SEC基板、もしくは、smoothstepperからのPWM信号をモーターのインターフェースに繋ぐので、
PWMから、DC ボルトのアナログにしたかったという点でしたよね?
ただ、リップルとか、スパイクとかは、ネット検索しましたが、よくわかりませんでした。
余計な電流という程度の理解です。
追伸
maboさんのプログラムですが、言われたとおりに変えたつもりですが、
どうして動作しなかったのかわからなくて、大変残念です。
若し、理由が分かれば教えてください。
No1519です。
点滅の件、ありがとございます。
あくまでも確認用ですね。
>私が取り上げたものなら,表示のライブラリーがありますので,比較的容易にできます。
特別な設定等もありません。あるとすれば,使用するピン
を #define で指定するだけです。
AD値などを確認できるのでしょうか?
済みませんが、URLを教えてください。
ローパスフィルターを入れない理由は、
自分の場合、ML4の可変抵抗の代わりに、デジタル可変抵抗を入れ替えるので、
うまくいったら、ローパスフィルターなしで行けるかもと思いました。
maboさんの場合は、自分と違って、
maboさんの場合は、
SEC基板、もしくは、smoothstepperからのPWM信号をモーターのインターフェースに繋ぐので、
PWMから、DC ボルトのアナログにしたかったという点でしたよね?
ただ、リップルとか、スパイクとかは、ネット検索しましたが、よくわかりませんでした。
余計な電流という程度の理解です。
追伸
maboさんのプログラムですが、言われたとおりに変えたつもりですが、
どうして動作しなかったのかわからなくて、大変残念です。
若し、理由が分かれば教えてください。
No1519です。
Re: 続続続続ーPWM
TRさん,LCDのライブラリーのURLちょっと失念です。
私の使ってるのアップしておきます。
http://mabo52.sakura.ne.jp/files/lcd-h.txt
http://mabo52.sakura.ne.jp/files/lcd-c.txt
使い方等は,下記見るとプログラムでてますので,
http://physics.cocolog-nifty.com/weblog/2012/07/post-b055.html
参考になるかと。
このファイル,コンパイルするとワーニングがでますが,
大丈夫です。
それぞれ,lcd.h lcd.c にして使ってください。
それと,
>自分の場合、ML4の可変抵抗の代わりに、デジタル可変抵抗を入れ替えるので、
>うまくいったら、ローパスフィルターなしで行けるかもと思いました。
これ,ちょっと違うかと思います。
MACHからの信号を受け取るのに,今回の私や猛牛ロックさんのプログラムは,
AD変換で受け取ってますので,抵抗とコンデンサーいれて,
直流変換してあげないと,受け取ることでないと思います。
猛牛ロックさんの言われたように,デジタルでそのまま受け取ってもいいのですが,
MACHから出てるPWMをそのままうけとるとなると,
PWMのDUTY比を計算しなければ,デジタルポテンショメーターの抵抗への換算できませんので,
外部割り込みやtimer割り込みで,サンプリングするなど,
手順がちょっと,面倒になるかと思います。
MACHからのPWMで直接モーターをコントロールできれば,
問題ないのですが。
今回は,間にデジタルポテンショメーターが入るので。
私の使ってるのアップしておきます。
http://mabo52.sakura.ne.jp/files/lcd-h.txt
http://mabo52.sakura.ne.jp/files/lcd-c.txt
使い方等は,下記見るとプログラムでてますので,
http://physics.cocolog-nifty.com/weblog/2012/07/post-b055.html
参考になるかと。
このファイル,コンパイルするとワーニングがでますが,
大丈夫です。
それぞれ,lcd.h lcd.c にして使ってください。
それと,
>自分の場合、ML4の可変抵抗の代わりに、デジタル可変抵抗を入れ替えるので、
>うまくいったら、ローパスフィルターなしで行けるかもと思いました。
これ,ちょっと違うかと思います。
MACHからの信号を受け取るのに,今回の私や猛牛ロックさんのプログラムは,
AD変換で受け取ってますので,抵抗とコンデンサーいれて,
直流変換してあげないと,受け取ることでないと思います。
猛牛ロックさんの言われたように,デジタルでそのまま受け取ってもいいのですが,
MACHから出てるPWMをそのままうけとるとなると,
PWMのDUTY比を計算しなければ,デジタルポテンショメーターの抵抗への換算できませんので,
外部割り込みやtimer割り込みで,サンプリングするなど,
手順がちょっと,面倒になるかと思います。
MACHからのPWMで直接モーターをコントロールできれば,
問題ないのですが。
今回は,間にデジタルポテンショメーターが入るので。
Re: 続続続続ーPWM
maboさんおはようございます。
早速に、ご紹介くださった ↓ を拝見しました。
http://physics.cocolog-nifty.com/weblog/2012/07/post-9765.html
液晶のSD1602から、PICにつながっているRB0,RB1,RB2,RB3があります。
PIC側の端子を変えるにはどうしたらよいでしょうか?
下記タイトルプログラムを見ると、itoa(str,tmp,10);
lcd_clear(); //表示クリア
lcd_goto(0); //カーソルを0行目の先頭に移動する
lcd_puts(str);
lcd_puts("mV");
この部分が怪しい??
使い方の確認ですが、
PICを写真のように結線し、PICにプログラムを書き込めばOKでしょうか?
必要なものは、
SD1602と液晶のコントラスト調整用にSD1602のVO端子に10kオームの
可変抵抗をつなぐだけみたいですが、よろしいでしょうか?
記
プログラムタイトル
/************************************
16F88 HI-TECH C v.9.83
RA0(AN0)の入力電圧をA/D変換してLCDに表示する
************************************/
略
それと、maboooooさんの ↓のプログラムと、ご紹介くださったPICに書き込むプログラムは
内容が違うようですけど、どういった使い分けをするのでしょうか?
http://mabo52.sakura.ne.jp/files/lcd-h.txt
http://mabo52.sakura.ne.jp/files/lcd-c.txt
そうか、maboさんのは、プロトタイプ宣言をした関数なんだ。
例えば、LCDをクリアしたいとすれば、次の関数を宣言するんだ ↓
* lcd_clear - ‚k‚b‚cƒ‚ƒWƒ…[ƒ‹‚̉æ–Ê‚ðÁ‚·ˆ— *
*******************************************************************************/
void lcd_clear(void){
LCD_RS = 0 ;
lcd_write(0x01) ; // Clear Display : ‰æ–Ê‘S‘Ì‚É20H‚̽Íß°½‚Å•\Ž¦A¶°¿Ù‚Ícol=0,row=0‚Ɉړ®
__delay_ms(2) ; // LCD‚ªˆ—(1.53ms)‚·‚é‚Ì‚ð‘Ò‚¿‚Ü‚·
}
でも、文字化けが凄いけど、気にしなくてOK??
早速に、ご紹介くださった ↓ を拝見しました。
http://physics.cocolog-nifty.com/weblog/2012/07/post-9765.html
液晶のSD1602から、PICにつながっているRB0,RB1,RB2,RB3があります。
PIC側の端子を変えるにはどうしたらよいでしょうか?
下記タイトルプログラムを見ると、itoa(str,tmp,10);
lcd_clear(); //表示クリア
lcd_goto(0); //カーソルを0行目の先頭に移動する
lcd_puts(str);
lcd_puts("mV");
この部分が怪しい??
使い方の確認ですが、
PICを写真のように結線し、PICにプログラムを書き込めばOKでしょうか?
必要なものは、
SD1602と液晶のコントラスト調整用にSD1602のVO端子に10kオームの
可変抵抗をつなぐだけみたいですが、よろしいでしょうか?
記
プログラムタイトル
/************************************
16F88 HI-TECH C v.9.83
RA0(AN0)の入力電圧をA/D変換してLCDに表示する
************************************/
略
それと、maboooooさんの ↓のプログラムと、ご紹介くださったPICに書き込むプログラムは
内容が違うようですけど、どういった使い分けをするのでしょうか?
http://mabo52.sakura.ne.jp/files/lcd-h.txt
http://mabo52.sakura.ne.jp/files/lcd-c.txt
そうか、maboさんのは、プロトタイプ宣言をした関数なんだ。
例えば、LCDをクリアしたいとすれば、次の関数を宣言するんだ ↓
* lcd_clear - ‚k‚b‚cƒ‚ƒWƒ…[ƒ‹‚̉æ–Ê‚ðÁ‚·ˆ— *
*******************************************************************************/
void lcd_clear(void){
LCD_RS = 0 ;
lcd_write(0x01) ; // Clear Display : ‰æ–Ê‘S‘Ì‚É20H‚̽Íß°½‚Å•\Ž¦A¶°¿Ù‚Ícol=0,row=0‚Ɉړ®
__delay_ms(2) ; // LCD‚ªˆ—(1.53ms)‚·‚é‚Ì‚ð‘Ò‚¿‚Ü‚·
}
でも、文字化けが凄いけど、気にしなくてOK??
Re: 続続続続ーPWM
TRさん,猛牛ロックさん,おはようございます。
TRさん,使い方ですが,まず
lcd-h.txt→→lcd.h
lcd-c.txt→→lcd.c
のように名前を変更してください。
文字化けは,ブラウザの表示で,エンコーディングの設定かえてみてください。
この二つのファイルが使うときに必要になりますが,この二つのファイルはいじりません。
適当な場所に保存しておいてください。私は,二つとも,
main.cと同じ場所に置いてあります。
XIDEで,次の操作をしてください。
main.cがおいてあると思いますが,
Source Files を右クリック
↓
Add Existing Item
で,lcd.c を選択して,Source Files にlcd.cを
付け加えてください。
同じように,Header Files を右クリック,Add Existing Item
で,lcd.hを加えてください。
あとは,main.c に下記のような必要な関数を書き加え
コンパイルすれば,LCDが使えるようになります。
lcd_init();lcd初期化
lcd_clear(); //表示クリア
lcd_goto(0); //カーソルを0行目の先頭に移動する
lcd_setCursor(0,0)
lcd_puts(str);
lcd_puts("mV")
文字化けだとういうことで,こちらに貼り付けて見ます。
使うピンを変更するには,lcd.cの
#define LCD_RS RA1
#define LCD_EN RA3
#define LCD_D4 RB4
#define LCD_D5 RB5
#define LCD_D6 RB6
#define LCD_D7 RB7
の部分を変更します。
表示するには,文字の操作が必要になりますので,
前回紹介した,PICのお勉強 さんのHPのプログラム
参考にしてみてください。
itoa(str,hozon,10);
が必要です。
ーーーーlcd.hーーーー
/*
* LCD interface header file
* See lcd.c for more info
*/
/* write a byte to the LCD in 4 bit mode */
extern void lcd_write(unsigned char);
/* Clear and home the LCD */
extern void lcd_clear(void);
/* write a string of characters to the LCD */
extern void lcd_puts(const char * s);
/* Go to the specified position */
//extern void lcd_goto(unsigned char);
extern void lcd_goto(unsigned char);
/* intialize the LCD - call before anything else */
extern void lcd_init(void);
extern void lcd_putch(char);
extern void lcd_setCursor(int,int);
/* Set the cursor position */
#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)
ーーーーーlcd.cーーーー
#include <stdlib.h>
#include <pic.h>
#include <htc.h> // delay用
#define _XTAL_FREQ 8000000
#include "lcd.h"
/*******************************************************************************
* 異なるピンを使う場合はここを変更する *
*******************************************************************************/
#define LCD_RS RA1
#define LCD_EN RA3
#define LCD_D4 RB4
#define LCD_D5 RB5
#define LCD_D6 RB6
#define LCD_D7 RB7
#define LCD_STROBE() ((LCD_EN=1),(LCD_EN=0))
/*******************************************************************************
* 秋月LCDピン配列 *
*******************************************************************************/
//LCD_RS・・・4
//LCD_EN・・・6
//LCD_D4・・・11
//LCD_D5・・・12
//LCD_D6・・・13
//LCD_D7・・・14
/*******************************************************************************
* lcd_write-LCDにデータを送信 *
*******************************************************************************/
void lcd_write(unsigned char c){
// 送信データのバイト列上位4ビットを処理
LCD_D4 = ( ( c >> 4 ) & 0x01 ) ;
LCD_D5 = ( ( c >> 5 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 6 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 7 ) & 0x01 ) ;
LCD_STROBE() ;
// 送信データのバイト列下位4ビットを処理
LCD_D4 = ( ( c ) & 0x01 ) ;
LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
LCD_STROBE() ;
}
/*******************************************************************************
* command- LCDにコマンドを発行する処理 *
*******************************************************************************/
void command(unsigned char c){
LCD_RS = 0 ;
LCD_D4 = ( ( c ) & 0x01 ) ;
LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
LCD_STROBE() ;
}
/*******************************************************************************
* lcd_clear - LCDモジュールの画面を消す処理 *
*******************************************************************************/
void lcd_clear(void){
LCD_RS = 0 ;
lcd_write(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
__delay_ms(2) ; // LCDが処理(1.53ms)するのを待ちます
}
/*******************************************************************************
* lcd_setCursor - LCDモジュール画面内のカーソル位置を移動する処理 *
* col : 横(列)方向のカーソル位置(0-15) *
* row : 縦(行)方向のカーソル位置(0-1) *
********************************************************************************/
void lcd_setCursor(int col, int row){
int row_offsets[] = { 0x00, 0x40 } ;
LCD_RS = 0 ;
lcd_write(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-0FH,40H-4FH
}
/*******************************************************************************
* lcd_putc - LCDにデータを1バイト出力する処理 *
* c : 出力する文字データ *
*******************************************************************************/
void lcd_putc(char c){
LCD_RS = 1 ; // RSの制御信号線をセットします
lcd_write( c ) ; // LCDにデータの送信
}
/*******************************************************************************
* lcd_goto - Go to the specified position *
* c : 出力する文字データ *
*******************************************************************************/
void lcd_goto(unsigned char pos){
LCD_RS = 0;
lcd_write(0x80+pos);
}
/*******************************************************************************
* lcd_puts - LCDに文字列データを出力する処理(文字列をNULL(0x00)まで繰返し出力)*
* s : 出力する文字列のデータ *
*******************************************************************************/
void lcd_puts(const char * s){
LCD_RS = 1 ; // RSの制御信号線をセットします
while(*s) lcd_write(*s++) ;
}
/*******************************************************************************
* lcd_init - LCDの初期化処理 *
*******************************************************************************/
void lcd_init(){
LCD_RS = 0 ;
LCD_EN = 0 ;
__delay_ms(30) ; // 電源ON後15msまで待ってから初期化
// LCDの立上げ時のチェックデータ(イニシャライズ処理用)を設定
command(0x03) ;
__delay_ms(10) ;
command(0x02) ;
// LCDにコマンドを発行します
lcd_write(0x28) ; // function set : データ線は4本・表示は2行・フォントは5x8ドット
lcd_write(0x0c) ; // display control: 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF
lcd_clear() ; // Clear Display : 画面をクリアし、カーソル位置はcol=0,row=0
lcd_write(0x06) ; // entry mode set : 文字を表示した次にカーソルを移動するを指示
}
TRさん,使い方ですが,まず
lcd-h.txt→→lcd.h
lcd-c.txt→→lcd.c
のように名前を変更してください。
文字化けは,ブラウザの表示で,エンコーディングの設定かえてみてください。
この二つのファイルが使うときに必要になりますが,この二つのファイルはいじりません。
適当な場所に保存しておいてください。私は,二つとも,
main.cと同じ場所に置いてあります。
XIDEで,次の操作をしてください。
main.cがおいてあると思いますが,
Source Files を右クリック
↓
Add Existing Item
で,lcd.c を選択して,Source Files にlcd.cを
付け加えてください。
同じように,Header Files を右クリック,Add Existing Item
で,lcd.hを加えてください。
あとは,main.c に下記のような必要な関数を書き加え
コンパイルすれば,LCDが使えるようになります。
lcd_init();lcd初期化
lcd_clear(); //表示クリア
lcd_goto(0); //カーソルを0行目の先頭に移動する
lcd_setCursor(0,0)
lcd_puts(str);
lcd_puts("mV")
文字化けだとういうことで,こちらに貼り付けて見ます。
使うピンを変更するには,lcd.cの
#define LCD_RS RA1
#define LCD_EN RA3
#define LCD_D4 RB4
#define LCD_D5 RB5
#define LCD_D6 RB6
#define LCD_D7 RB7
の部分を変更します。
表示するには,文字の操作が必要になりますので,
前回紹介した,PICのお勉強 さんのHPのプログラム
参考にしてみてください。
itoa(str,hozon,10);
が必要です。
ーーーーlcd.hーーーー
/*
* LCD interface header file
* See lcd.c for more info
*/
/* write a byte to the LCD in 4 bit mode */
extern void lcd_write(unsigned char);
/* Clear and home the LCD */
extern void lcd_clear(void);
/* write a string of characters to the LCD */
extern void lcd_puts(const char * s);
/* Go to the specified position */
//extern void lcd_goto(unsigned char);
extern void lcd_goto(unsigned char);
/* intialize the LCD - call before anything else */
extern void lcd_init(void);
extern void lcd_putch(char);
extern void lcd_setCursor(int,int);
/* Set the cursor position */
#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)
ーーーーーlcd.cーーーー
#include <stdlib.h>
#include <pic.h>
#include <htc.h> // delay用
#define _XTAL_FREQ 8000000
#include "lcd.h"
/*******************************************************************************
* 異なるピンを使う場合はここを変更する *
*******************************************************************************/
#define LCD_RS RA1
#define LCD_EN RA3
#define LCD_D4 RB4
#define LCD_D5 RB5
#define LCD_D6 RB6
#define LCD_D7 RB7
#define LCD_STROBE() ((LCD_EN=1),(LCD_EN=0))
/*******************************************************************************
* 秋月LCDピン配列 *
*******************************************************************************/
//LCD_RS・・・4
//LCD_EN・・・6
//LCD_D4・・・11
//LCD_D5・・・12
//LCD_D6・・・13
//LCD_D7・・・14
/*******************************************************************************
* lcd_write-LCDにデータを送信 *
*******************************************************************************/
void lcd_write(unsigned char c){
// 送信データのバイト列上位4ビットを処理
LCD_D4 = ( ( c >> 4 ) & 0x01 ) ;
LCD_D5 = ( ( c >> 5 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 6 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 7 ) & 0x01 ) ;
LCD_STROBE() ;
// 送信データのバイト列下位4ビットを処理
LCD_D4 = ( ( c ) & 0x01 ) ;
LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
LCD_STROBE() ;
}
/*******************************************************************************
* command- LCDにコマンドを発行する処理 *
*******************************************************************************/
void command(unsigned char c){
LCD_RS = 0 ;
LCD_D4 = ( ( c ) & 0x01 ) ;
LCD_D5 = ( ( c >> 1 ) & 0x01 ) ;
LCD_D6 = ( ( c >> 2 ) & 0x01 ) ;
LCD_D7 = ( ( c >> 3 ) & 0x01 ) ;
LCD_STROBE() ;
}
/*******************************************************************************
* lcd_clear - LCDモジュールの画面を消す処理 *
*******************************************************************************/
void lcd_clear(void){
LCD_RS = 0 ;
lcd_write(0x01) ; // Clear Display : 画面全体に20Hのスペースで表示、カーソルはcol=0,row=0に移動
__delay_ms(2) ; // LCDが処理(1.53ms)するのを待ちます
}
/*******************************************************************************
* lcd_setCursor - LCDモジュール画面内のカーソル位置を移動する処理 *
* col : 横(列)方向のカーソル位置(0-15) *
* row : 縦(行)方向のカーソル位置(0-1) *
********************************************************************************/
void lcd_setCursor(int col, int row){
int row_offsets[] = { 0x00, 0x40 } ;
LCD_RS = 0 ;
lcd_write(0x80 | (col + row_offsets[row])) ; // Set DDRAM Adddress : 00H-0FH,40H-4FH
}
/*******************************************************************************
* lcd_putc - LCDにデータを1バイト出力する処理 *
* c : 出力する文字データ *
*******************************************************************************/
void lcd_putc(char c){
LCD_RS = 1 ; // RSの制御信号線をセットします
lcd_write( c ) ; // LCDにデータの送信
}
/*******************************************************************************
* lcd_goto - Go to the specified position *
* c : 出力する文字データ *
*******************************************************************************/
void lcd_goto(unsigned char pos){
LCD_RS = 0;
lcd_write(0x80+pos);
}
/*******************************************************************************
* lcd_puts - LCDに文字列データを出力する処理(文字列をNULL(0x00)まで繰返し出力)*
* s : 出力する文字列のデータ *
*******************************************************************************/
void lcd_puts(const char * s){
LCD_RS = 1 ; // RSの制御信号線をセットします
while(*s) lcd_write(*s++) ;
}
/*******************************************************************************
* lcd_init - LCDの初期化処理 *
*******************************************************************************/
void lcd_init(){
LCD_RS = 0 ;
LCD_EN = 0 ;
__delay_ms(30) ; // 電源ON後15msまで待ってから初期化
// LCDの立上げ時のチェックデータ(イニシャライズ処理用)を設定
command(0x03) ;
__delay_ms(10) ;
command(0x02) ;
// LCDにコマンドを発行します
lcd_write(0x28) ; // function set : データ線は4本・表示は2行・フォントは5x8ドット
lcd_write(0x0c) ; // display control: 画面表示はON・カーソル表示はOFF・カーソル点滅はOFF
lcd_clear() ; // Clear Display : 画面をクリアし、カーソル位置はcol=0,row=0
lcd_write(0x06) ; // entry mode set : 文字を表示した次にカーソルを移動するを指示
}
Re: 続続続続ーPWM
追記です。
「PICのお勉強」 さんのプログラムや,
結線仕方を参考になるかと思います。
別なプログラムで,LCDを使うのには,
同じように,lcd.c と lcd.h を付け加えます。
main.cのプログラムから,この二つを参照する形です。
main.cの先頭には,
#include "lcd.h"
を書いてください。
プロジェクトにきちんと付け加えられていれば,
いつものようにコンパイルすると,二つのcのプログラムが
それぞれコンパイルされて,一つになります。
蛇足ですが,チャージポンプの回路,LCDに組み込むと,
3V〜5Vの範囲で使えるようになりますが,
ちょっと,面倒です。
http://mabo52.sakura.ne.jp/index.php?e=1202
「PICのお勉強」 さんのプログラムや,
結線仕方を参考になるかと思います。
別なプログラムで,LCDを使うのには,
同じように,lcd.c と lcd.h を付け加えます。
main.cのプログラムから,この二つを参照する形です。
main.cの先頭には,
#include "lcd.h"
を書いてください。
プロジェクトにきちんと付け加えられていれば,
いつものようにコンパイルすると,二つのcのプログラムが
それぞれコンパイルされて,一つになります。
蛇足ですが,チャージポンプの回路,LCDに組み込むと,
3V〜5Vの範囲で使えるようになりますが,
ちょっと,面倒です。
http://mabo52.sakura.ne.jp/index.php?e=1202
続続続ーPWM
TRさん,こんにちは。
頑張っておられますね。
PWM発生機は不良品ではなくて,仕様みたいな感じです。
ところで,1503のTRさんのプログラムですが,
いくつか追加と修正点で,シンタックスエラーはなくなり,
コンパイルも通るようになりました。
追加は,abs()の組み込み関数を使うためのライブラリーのインクルードです。
数学系の関数や,文字操作の組み込み関数?を使うときは,
専用のインクルードファイルを取り込まないとだめみたいです。
それから,else は,二つあるとだめみたいです。
思うようにいかなかったのは,全角の空白が入ってました。
以下が一応,エラーのなくなったプログラムです。
/*RB4で電圧読み取り*/
//RB7が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニターLED緑で点滅させる
//RA0は電圧DownのモニターLED黄で点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//RA4はINCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdlib.h>
#include <math.h>
unsigned int adconv(void) ;//ADC読み込み関数
void main(void);
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
//メイン関数
void main(void){
int i;
int hozon=1024;
int newhozon=1024;
//OPTION_REGbits.nWPUEN = 0;//内部プルアップ有効
OSCCON = 0b0111001;//クロック周波数を16MHzに設定
PORTA = 0x00;//全てLo
PORTB = 0x00;//全てLo
ANSELA = 0b00000000;//全てデジタルI/Oとする
ANSELB = 0b00010000;// 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000;// RA全て出力
TRISB = 0b10010000;//RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001;// アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000;// 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
while (1) {
hozon=adconv( );//adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if(hozon != adconv( )){
newhozon=adconv( );
RA2=0;//CSピンコマンド待ち
for(i=0 ; i < (abs(hozon-newhozon)/100) ; i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=!LATA1;
__delay_us(100);//調整の必要ありそう
LATA1=0;
}
else if((hozon-newhozon)<0){
RA3=0;//U/Dピンをダウンに設定
LATA0=!LATA0;
__delay_us(100);//調整の必要ありそう
LATA0=0;
}
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv(void) {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
シンタックスエラー等はなくなりましたが,
実際に思った動作をするかどうかは,たしかめで,
アルゴリズム等,考える必要あるかもしれません。
時間みて,私も,LEDでシュミレートしてみます。
頑張っておられますね。
PWM発生機は不良品ではなくて,仕様みたいな感じです。
ところで,1503のTRさんのプログラムですが,
いくつか追加と修正点で,シンタックスエラーはなくなり,
コンパイルも通るようになりました。
追加は,abs()の組み込み関数を使うためのライブラリーのインクルードです。
数学系の関数や,文字操作の組み込み関数?を使うときは,
専用のインクルードファイルを取り込まないとだめみたいです。
それから,else は,二つあるとだめみたいです。
思うようにいかなかったのは,全角の空白が入ってました。
以下が一応,エラーのなくなったプログラムです。
/*RB4で電圧読み取り*/
//RB7が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニターLED緑で点滅させる
//RA0は電圧DownのモニターLED黄で点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//RA4はINCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <stdlib.h>
#include <math.h>
unsigned int adconv(void) ;//ADC読み込み関数
void main(void);
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
//メイン関数
void main(void){
int i;
int hozon=1024;
int newhozon=1024;
//OPTION_REGbits.nWPUEN = 0;//内部プルアップ有効
OSCCON = 0b0111001;//クロック周波数を16MHzに設定
PORTA = 0x00;//全てLo
PORTB = 0x00;//全てLo
ANSELA = 0b00000000;//全てデジタルI/Oとする
ANSELB = 0b00010000;// 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000;// RA全て出力
TRISB = 0b10010000;//RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001;// アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000;// 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
while (1) {
hozon=adconv( );//adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if(hozon != adconv( )){
newhozon=adconv( );
RA2=0;//CSピンコマンド待ち
for(i=0 ; i < (abs(hozon-newhozon)/100) ; i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=!LATA1;
__delay_us(100);//調整の必要ありそう
LATA1=0;
}
else if((hozon-newhozon)<0){
RA3=0;//U/Dピンをダウンに設定
LATA0=!LATA0;
__delay_us(100);//調整の必要ありそう
LATA0=0;
}
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv(void) {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
シンタックスエラー等はなくなりましたが,
実際に思った動作をするかどうかは,たしかめで,
アルゴリズム等,考える必要あるかもしれません。
時間みて,私も,LEDでシュミレートしてみます。
Re: 続続続ーPWM
maboさん有り難うございます。
一人でもがいていました。
for(i=0 ; i < (abs(hozon-newhozon)/100) ; 
これですが、デジタルポテンションメーターを使う場合、/100は不用?
ledの実験楽しみに待ちます。
後、デジタルポテンションメーターに繋げばOK?
それと、absを使うためのライブラリー
stdlb.hですね?
一人でもがいていました。
for(i=0 ; i < (abs(hozon-newhozon)/100) ; 
これですが、デジタルポテンションメーターを使う場合、/100は不用?
ledの実験楽しみに待ちます。
後、デジタルポテンションメーターに繋げばOK?
それと、absを使うためのライブラリー
stdlb.hですね?
Re: 続続続ーPWM
maboさん、続けて失礼します。
UP/DOWNのモニター用LEDのプログラムを少し変えて、実験しましたが、、
RB4(SEC基板PORT2の14番)のHi/Loに連動しません。
狙った動作 ↓
RB4 HI→LATA1がHiでLATA0がLo
RB4 Lo→LATA1がLoでLATA0がLo
上の問題もあるのですが、
ご紹介をいただいたURLのデジタル抵抗の使い方を見ると
****
SPIのようにCSピンがLoになるとコマンド入力待ちなり、INCピンの立下りエッジでRw/Vw端子が移動します。
更に、U/DピンがHi→大きい方へ
U/DピンがLo→小さい方へ
****
となっています。
で、
MACH3の信号(SEC基板PORT2の14番)をU/Dに繋げますが、CSピンをLoにするにはどうしたらよいのでしょうか?
プログラムで、PICの端子をLoとし、
その端子をCSピンにつなぐのでしょうか?
追記
※
今、可変抵抗をつけて実験したら、まったくモニター用LEDが点滅しなくなりました。
タクトSWの時は点滅したのに!!
今気が付きました。
プログラムに あった ↓
newhozon=adconv( );
RA2=0;//CSピンコマンド待ち
UP/DOWNのモニター用LEDのプログラムを少し変えて、実験しましたが、、
RB4(SEC基板PORT2の14番)のHi/Loに連動しません。
狙った動作 ↓
RB4 HI→LATA1がHiでLATA0がLo
RB4 Lo→LATA1がLoでLATA0がLo
上の問題もあるのですが、
ご紹介をいただいたURLのデジタル抵抗の使い方を見ると
****
SPIのようにCSピンがLoになるとコマンド入力待ちなり、INCピンの立下りエッジでRw/Vw端子が移動します。
更に、U/DピンがHi→大きい方へ
U/DピンがLo→小さい方へ
****
となっています。
で、
MACH3の信号(SEC基板PORT2の14番)をU/Dに繋げますが、CSピンをLoにするにはどうしたらよいのでしょうか?
プログラムで、PICの端子をLoとし、
その端子をCSピンにつなぐのでしょうか?
追記
※
今、可変抵抗をつけて実験したら、まったくモニター用LEDが点滅しなくなりました。
タクトSWの時は点滅したのに!!
今気が付きました。
プログラムに あった ↓
newhozon=adconv( );
RA2=0;//CSピンコマンド待ち
Re: 続続続ーPWM
TRさん,こんばんは。
早いですね。いろいろなさってますね。
当たり前ですが,マニュアルあるようです。
http://www.farnell.com/datasheets/18974.pdf
これにもあるのですが,使う抵抗によって,一度に動かせる
数値が決まってるようですね。
X9C102 1KΩ 10.1Ω 40Ω
X9C103 10KΩ 101Ω 40Ω
X9C503 50KΩ 505Ω 40Ω
X9C104 100KΩ 1010Ω 40Ω
これとの兼ね合いで,どの程度の精度で動かすのか,
によって,
>for(i=0 ; i < (abs(hozon-newhozon)/100) ; 
>これですが、デジタルポテンションメーターを使う場合、/100は不用?
の/100の数値は決めるようでしょうね。
>それと、absを使うためのライブラリー
>stdlb.hですね?
#include <stdlib.h>
でしたね。この辺私もその都度調べてます。
それから,TRさん,まだSECの基盤にはつながない方がいいです。
SECさんの基盤とつなぐのは,PICでの動作が正常に動くようになってからの方がいいと思います。
それから,SECさんの基盤とつなぐのは,PWMの出力を
アナログ変換した信号を取るものだけです。
>CSピンをLoにするにはどうしたらよいのでしょうか?
これは,MACHからの信号をプログラムで判断して,
PICで操作です。
MACH−−−−−PIC−−−−−デジタルポテンショメーター
2本の線 3本の線
みたいな感じです。
マッハからの信号をボリュームでシュミレート。
PICからデジタルポテンショメーターへの3本の線の
信号を3つのLEDシュミレートという感じです。
ーーー追伸ーーー
今,シュミレートのプログラムと,ハードを組み立ててます。
MACHからの信号読み取るのに,LCDで表示するための
準備してます。
これも,ちょっと面倒で,ちょっと,時間かかります。
環境ができれば,あとはシュミレートして,不具合を修正
すればいいと思いますので,時間がかかるかと思いますけど,
できそうな気がします。
早いですね。いろいろなさってますね。
当たり前ですが,マニュアルあるようです。
http://www.farnell.com/datasheets/18974.pdf
これにもあるのですが,使う抵抗によって,一度に動かせる
数値が決まってるようですね。
X9C102 1KΩ 10.1Ω 40Ω
X9C103 10KΩ 101Ω 40Ω
X9C503 50KΩ 505Ω 40Ω
X9C104 100KΩ 1010Ω 40Ω
これとの兼ね合いで,どの程度の精度で動かすのか,
によって,
>for(i=0 ; i < (abs(hozon-newhozon)/100) ; 
>これですが、デジタルポテンションメーターを使う場合、/100は不用?
の/100の数値は決めるようでしょうね。
>それと、absを使うためのライブラリー
>stdlb.hですね?
#include <stdlib.h>
でしたね。この辺私もその都度調べてます。
それから,TRさん,まだSECの基盤にはつながない方がいいです。
SECさんの基盤とつなぐのは,PICでの動作が正常に動くようになってからの方がいいと思います。
それから,SECさんの基盤とつなぐのは,PWMの出力を
アナログ変換した信号を取るものだけです。
>CSピンをLoにするにはどうしたらよいのでしょうか?
これは,MACHからの信号をプログラムで判断して,
PICで操作です。
MACH−−−−−PIC−−−−−デジタルポテンショメーター
2本の線 3本の線
みたいな感じです。
マッハからの信号をボリュームでシュミレート。
PICからデジタルポテンショメーターへの3本の線の
信号を3つのLEDシュミレートという感じです。
ーーー追伸ーーー
今,シュミレートのプログラムと,ハードを組み立ててます。
MACHからの信号読み取るのに,LCDで表示するための
準備してます。
これも,ちょっと面倒で,ちょっと,時間かかります。
環境ができれば,あとはシュミレートして,不具合を修正
すればいいと思いますので,時間がかかるかと思いますけど,
できそうな気がします。
Re: 続続続ーPWM
maboさん、おはようございます。
自分ですが、年齢とともに、こういった分野に興味がわいてきています。
バイクとPICに、今は、興味津々です。
当方のレスは、写真の関係で2つに分けます。
先ず、その1
>これにもあるのですが,使う抵抗によって,一度に動かせる
数値が決まってるようですね。
データシートですが、グーグル翻訳でみると、
多分写真のところでしょうかね。
でも、maboさん、英語も分かるんですね!!
データシートの赤部分 ↓
FEATURES
100 Wiper Tap Points
となっているから、100で割っているんですね。
つまり、100単位、でも、1024を100で割るのかな〜?
100Ω単位なら、違うような気もしますが、はっきりとしません。
可変抵抗のBカーブならいいような、下限値40Ωを除いて1024としても、1024は約1000なので、
いいような気もします。
本来は、40Ω分を除くかな?
以前、猛牛ロックさんが、自分のクーラントポンプの時に、計算してくれた表がありましたよね。
No1388にあります。
自分ですが、年齢とともに、こういった分野に興味がわいてきています。
バイクとPICに、今は、興味津々です。
当方のレスは、写真の関係で2つに分けます。
先ず、その1
>これにもあるのですが,使う抵抗によって,一度に動かせる
数値が決まってるようですね。
データシートですが、グーグル翻訳でみると、
多分写真のところでしょうかね。
でも、maboさん、英語も分かるんですね!!
データシートの赤部分 ↓
FEATURES
100 Wiper Tap Points
となっているから、100で割っているんですね。
つまり、100単位、でも、1024を100で割るのかな〜?
100Ω単位なら、違うような気もしますが、はっきりとしません。
可変抵抗のBカーブならいいような、下限値40Ωを除いて1024としても、1024は約1000なので、
いいような気もします。
本来は、40Ω分を除くかな?
以前、猛牛ロックさんが、自分のクーラントポンプの時に、計算してくれた表がありましたよね。
No1388にあります。
Re: 続続続ーPWM
その2
>それから,SECさんの基盤とつなぐのは,PWMの出力を
アナログ変換した信号を取るものだけです。
繋ぎ方は 、図面をアップしますので、見て頂けませんか。m(__)m
現在は、SEC基板からの信号をテスト用のコンタクトSWとテスト用 2の可変抵抗でやっています。
※ テスト用 2の可変抵抗だと全くLEDが点滅しません。
変えたプログラム末尾に!
補足
PICのヘッダー
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニター赤LEDで点滅させる
//RA4はデジタル抵抗のCSピンモニター用の緑LED ※ 新たに追加!!!
//RA0は電圧Downのモニター黄色LEDで点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//INCピンはプルアップで常時HIにする
凄いのができそうですね。
LCDモニターがよさそうですね。
自分のレベルでは難しいかな〜。
ワクワクしてきました。
末尾
for(i=0 ; i < (abs(hozon-newhozon)/100) ; i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=1;
__delay_us(10);//調整の必要ありそう
LATA0=0;
__delay_us(10);
}
else if((hozon-newhozon)<0){
__delay_us(10);
RA3=0;//U/Dピンをダウンに設定
LATA0=1;
__delay_us(10);//調整の必要ありそう
LATA1=0;
__delay_us(10);
}
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
}
>それから,SECさんの基盤とつなぐのは,PWMの出力を
アナログ変換した信号を取るものだけです。
繋ぎ方は 、図面をアップしますので、見て頂けませんか。m(__)m
現在は、SEC基板からの信号をテスト用のコンタクトSWとテスト用 2の可変抵抗でやっています。
※ テスト用 2の可変抵抗だと全くLEDが点滅しません。
変えたプログラム末尾に!
補足
PICのヘッダー
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニター赤LEDで点滅させる
//RA4はデジタル抵抗のCSピンモニター用の緑LED ※ 新たに追加!!!
//RA0は電圧Downのモニター黄色LEDで点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//INCピンはプルアップで常時HIにする
凄いのができそうですね。
LCDモニターがよさそうですね。
自分のレベルでは難しいかな〜。
ワクワクしてきました。
末尾
for(i=0 ; i < (abs(hozon-newhozon)/100) ; i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=1;
__delay_us(10);//調整の必要ありそう
LATA0=0;
__delay_us(10);
}
else if((hozon-newhozon)<0){
__delay_us(10);
RA3=0;//U/Dピンをダウンに設定
LATA0=1;
__delay_us(10);//調整の必要ありそう
LATA1=0;
__delay_us(10);
}
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
}
Re: 続続続ーPWM
MABOさん、TRさん、ご無沙汰してます。
えーと、TRさんのX9Cですけど、基本的に3本制御ですね。2本でも可能なようですけど
データシートの3ページの表(Mode Selection)を見る限り、その接続ではWIPERを上げ下げ出来ません。
2本にしたいのならCSピンをGNDに接続して固定します。
(但し、その使い方では位置は記憶できません。)
で、U/Dピンを選択して、INCピンを下げた時にストローブです。
もう一点、この類のICは非常に出力が小さいです。
(出力可能な電圧は1mAほど。損失も10mW以下にする必要があります)
モーター側の電圧が5Vらしいので、多分ADCで入力していて大丈夫のような気はしますけど、
簡単なテストをしておいた方が良いです。
※本来、7ページ(Basic Circuits)に載っているように、オペアンプでバッファを取り、出力を増強させて使います。
ついでに言えば、折角のPICですから、こういった時はPIC16F1705のようなDACの付いたマイコンを使うのが良いです。
DACの付いているPICの殆どがオペアンプもあります。つまり、内部でオペアンプに繋いで安定した電圧で
出力する事が可能です。(といってもそんなに能力は無いでしょうけど)
これは、UNOあたりのArduinoには出来ない芸当です。
1705で、8ビットのDACですから、256段階で指定できることになります。
当たり前ですけど、ピンの上げ下げをすることなく、レジスタに値を入れるだけです。
(といっても、使いこなすには経験が必要でしょうけど→私も使った事はありません)
※添付図は1705のデータシートから。
えーと、TRさんのX9Cですけど、基本的に3本制御ですね。2本でも可能なようですけど
データシートの3ページの表(Mode Selection)を見る限り、その接続ではWIPERを上げ下げ出来ません。
2本にしたいのならCSピンをGNDに接続して固定します。
(但し、その使い方では位置は記憶できません。)
で、U/Dピンを選択して、INCピンを下げた時にストローブです。
もう一点、この類のICは非常に出力が小さいです。
(出力可能な電圧は1mAほど。損失も10mW以下にする必要があります)
モーター側の電圧が5Vらしいので、多分ADCで入力していて大丈夫のような気はしますけど、
簡単なテストをしておいた方が良いです。
※本来、7ページ(Basic Circuits)に載っているように、オペアンプでバッファを取り、出力を増強させて使います。
ついでに言えば、折角のPICですから、こういった時はPIC16F1705のようなDACの付いたマイコンを使うのが良いです。
DACの付いているPICの殆どがオペアンプもあります。つまり、内部でオペアンプに繋いで安定した電圧で
出力する事が可能です。(といってもそんなに能力は無いでしょうけど)
これは、UNOあたりのArduinoには出来ない芸当です。
1705で、8ビットのDACですから、256段階で指定できることになります。
当たり前ですけど、ピンの上げ下げをすることなく、レジスタに値を入れるだけです。
(といっても、使いこなすには経験が必要でしょうけど→私も使った事はありません)
※添付図は1705のデータシートから。
Re: 続続続ーPWM
猛牛ロックさん、ご薫陶感謝申し上げます。
ここ数日、プログラムを考えていました。
No1506のプログラムですが、思うように動作しません。
No1506は、そのほかにも ↓
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
上のように、// 〇〇〇//
というように//で囲っています。
そこで、Swtich関数を使って、以下のようにしましたが、
それでも、思った動作をしません。
すみませんが見て頂けませんかm(__)m。
/*RB4で電圧読み取り*/
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニター赤LEDで点滅させる
//RA4はデジタル抵抗のCSピンモニター用の緑LED
//RA0は電圧Downのモニター黄色LEDで点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//INCピンはプルアップで常時HIにする
//INCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
略
#include <xc.h>
#include <stdlib.h>
#include <math.h>
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
void main(void);
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
//メイン関数
void main(void) {
int i;
int hozon = 1024;
int newhozon = 1024;
//OPTION_REGbits.nWPUEN = 0;//内部プルアップ有効
OSCCON = 0b0111001; //クロック周波数を16MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b10010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
int a = hozon - newhozon;
while (1) {
hozon = adconv(); //adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if (hozon != adconv()) {
newhozon = adconv();
switch (a) {
case 'a' > 0:
for (i = 0; i < (abs(hozon - newhozon) / 100); i++) {
RA2 = 0; //CSピンコマンド待ち
RA3 = 1; //U/Dピンをアップに設定
LATA0 = 1;//黄色LEDダウンモニター
break;
}
case 'a' < 0:
for (i = 0; i < (abs(hozon - newhozon) / 100); i++) {
RA2 = 0; //CSピンコマンド待ち
RA3 = 0; //U/Dピンをダウンに設定
LATA1 = 1;
break;
}
default:RA2 = 1;//CSピンHi
break;
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv(void) {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
ここ数日、プログラムを考えていました。
No1506のプログラムですが、思うように動作しません。
No1506は、そのほかにも ↓
//else{
RA2 = 1;//CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
//}
上のように、// 〇〇〇//
というように//で囲っています。
そこで、Swtich関数を使って、以下のようにしましたが、
それでも、思った動作をしません。
すみませんが見て頂けませんかm(__)m。
/*RB4で電圧読み取り*/
//RB4が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニター赤LEDで点滅させる
//RA4はデジタル抵抗のCSピンモニター用の緑LED
//RA0は電圧Downのモニター黄色LEDで点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//INCピンはプルアップで常時HIにする
//INCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
略
#include <xc.h>
#include <stdlib.h>
#include <math.h>
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
void main(void);
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
//メイン関数
void main(void) {
int i;
int hozon = 1024;
int newhozon = 1024;
//OPTION_REGbits.nWPUEN = 0;//内部プルアップ有効
OSCCON = 0b0111001; //クロック周波数を16MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b10010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
int a = hozon - newhozon;
while (1) {
hozon = adconv(); //adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if (hozon != adconv()) {
newhozon = adconv();
switch (a) {
case 'a' > 0:
for (i = 0; i < (abs(hozon - newhozon) / 100); i++) {
RA2 = 0; //CSピンコマンド待ち
RA3 = 1; //U/Dピンをアップに設定
LATA0 = 1;//黄色LEDダウンモニター
break;
}
case 'a' < 0:
for (i = 0; i < (abs(hozon - newhozon) / 100); i++) {
RA2 = 0; //CSピンコマンド待ち
RA3 = 0; //U/Dピンをダウンに設定
LATA1 = 1;
break;
}
default:RA2 = 1;//CSピンHi
break;
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv(void) {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
Re: 続続続ーPWM
TRさん,猛牛ロックさんおはようございます。
猛牛ロックさん,ご意見いただけると,心強いです。
TRさん,回路図のことは,読み取りができず,アドバイス等
とんでもない話ですけど,
MACHからの信号には,
抵抗とコンデンサー入れる必要あるようです。
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
に回路図のってます。
私の環境で,もがきました。
詳細は,今夜書きます。
if(hozon != adconv( )){ }
がだめでした。ADCの読み取りが安定しませんでした。
猛牛ロックさん,ご意見いただけると,心強いです。
TRさん,回路図のことは,読み取りができず,アドバイス等
とんでもない話ですけど,
MACHからの信号には,
抵抗とコンデンサー入れる必要あるようです。
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
に回路図のってます。
私の環境で,もがきました。
詳細は,今夜書きます。
if(hozon != adconv( )){ }
がだめでした。ADCの読み取りが安定しませんでした。
Re: 続続続ーPWM
プログラムは↑で言ったように、接続が違います。
で、上では3線コントロールが良いように言いましたけど、
値を保存してもいい事も無い気がします。つまり、csピンはプルダウンが良いです。
(電源を入れた時に一瞬動くことになるかもしれません)
MachからのPWM信号をフィルタを通してからアナログで取得としているようですけど、
フィルタを通しても値は振動します。振動させないようにするには、抵抗値とコンデンサの容量を大きくする必要がありますけど、
その場合は反応の遅さとして表れます。どの位が適しているかは、Machからの信号の周波数が元になります。
私の好みとしてはデジタルでそのまま読み取る方法かなぁ。
で、プログラムを見てみましたけど、実際の回転数が無いですよね?
構成としては、通常、
Machから何rpm(或いは停止)の命令が来たかの判断
つまり、ターゲットとなる回転数が決まります。
次にその回転数になるようにボリュームを操作するのでしょうけど、
現在が何rpm出ているのかを取得しないと、プログラムを繋げようがないです。
或いは、適当にrpmを100段階(抵抗の分解能)にしようとしているのでしょうか?
もし今、回転数計が付いていないなら、付けてみる機会だと思います。
プログラムは、大体、下記のような感じかと思います。
#define ud LATA○
#define inc LATA×
//外部変数
volatile char x9c_val;
void x9c_init(void){
ud=0;
for(char i=0;i<99;i++){
inc=0;
__delay_us(1);
inc=1;
__delay_us(500);
}
x9c_val=0;
}
void x9c_up(void){
ud=1;
inc=0;
__delay_us(1);
inc=1;
if(x9c_val<99)x9c_val++;
//次の上げ下げは500us空ける
}
void x9c_down(void){//TYPOを修正
ud=0;
inc=0;
__delay_us(1);
inc=1;
if(x9c_val>0)x9c_val--;
//次の上げ下げは500us空ける
}
void main(){
//略
x9c_init();
while(1){
static unsigned int adc[4]={0};
static char num=0;
unsigned int target=0;
adc[(++num)&3]=adconv();
for(char i=0;i<4;i++)target+=adc[i];
target/=40.9;
if(target>x9c_val)x9c_up();
else if(target<x9c_val)x9c_down();
__delay_ms(1);//TYPO修正
}
}
で、上では3線コントロールが良いように言いましたけど、
値を保存してもいい事も無い気がします。つまり、csピンはプルダウンが良いです。
(電源を入れた時に一瞬動くことになるかもしれません)
MachからのPWM信号をフィルタを通してからアナログで取得としているようですけど、
フィルタを通しても値は振動します。振動させないようにするには、抵抗値とコンデンサの容量を大きくする必要がありますけど、
その場合は反応の遅さとして表れます。どの位が適しているかは、Machからの信号の周波数が元になります。
私の好みとしてはデジタルでそのまま読み取る方法かなぁ。
で、プログラムを見てみましたけど、実際の回転数が無いですよね?
構成としては、通常、
Machから何rpm(或いは停止)の命令が来たかの判断
つまり、ターゲットとなる回転数が決まります。
次にその回転数になるようにボリュームを操作するのでしょうけど、
現在が何rpm出ているのかを取得しないと、プログラムを繋げようがないです。
或いは、適当にrpmを100段階(抵抗の分解能)にしようとしているのでしょうか?
もし今、回転数計が付いていないなら、付けてみる機会だと思います。
プログラムは、大体、下記のような感じかと思います。
#define ud LATA○
#define inc LATA×
//外部変数
volatile char x9c_val;
void x9c_init(void){
ud=0;
for(char i=0;i<99;i++){
inc=0;
__delay_us(1);
inc=1;
__delay_us(500);
}
x9c_val=0;
}
void x9c_up(void){
ud=1;
inc=0;
__delay_us(1);
inc=1;
if(x9c_val<99)x9c_val++;
//次の上げ下げは500us空ける
}
void x9c_down(void){//TYPOを修正
ud=0;
inc=0;
__delay_us(1);
inc=1;
if(x9c_val>0)x9c_val--;
//次の上げ下げは500us空ける
}
void main(){
//略
x9c_init();
while(1){
static unsigned int adc[4]={0};
static char num=0;
unsigned int target=0;
adc[(++num)&3]=adconv();
for(char i=0;i<4;i++)target+=adc[i];
target/=40.9;
if(target>x9c_val)x9c_up();
else if(target<x9c_val)x9c_down();
__delay_ms(1);//TYPO修正
}
}
Re: 続続続ーPWM
猛牛ロックさん,今晩は。
すっきりとしたプログラムありがとうございます。
多分,実際の使用を想定しプログラムですね。
私は,今,タイミングチャートは,ちょっと,度外視してます。
for(char i=0;i<4;i++)target+=adc[i];
target/=40.9;
部分は,移動平均でしょうか。
私がもがいてるのは,その前の段階で,動作をLED,LCDで,確認している段階です。
とりあえず,U/DとINCの2本の線の動作を頭においてます。
実際使うとなると,ワイパーの保持とか,ワイパーの閾値の処理とか,まだ未知の部分が多いので,とりあえずはというところです。
それから,
>その場合は反応の遅さとして表れます。どの位が適しているかは、Machからの信号の周波数が元になります。
>私の好みとしてはデジタルでそのまま読み取る方法かなぁ。
そうですね。デジタルを直接読み取るには,ちょっとプログラム組まないとですね。
PWMの基本周波数の変換のプログラムを移植しましたが,
理解するのに時間かかって,手こずりました。
その点,アナログでの受け取りは,反応速度の問題もあるでしょけど,ADCで読み取れるので,お手軽でしょうかね。
それと,MACHで,RPMの情報は,直接でてるのでしょうか。
ただ,RPMの情報あったとしても,それをもとにコントロールするとなると,PIDの調整等が必要でしょうから,
ちょっとハードルたかいかな,なんて思います。
>現在が何rpm出ているのかを取得しないと、プログラムを繋げようがないです。
>或いは、適当にrpmを100段階(抵抗の分解能)にしようとしているのでしょうか?
私個人は,とりあえず,10段階ぐらいの範囲で,スピードが
調整できればいいかなと思いました。
TRさん,こんばんは。
1514でも書きましたが,
if (hozon != adconv())
がだめでした。
ここを
if(abs((buffer-hozon))>10)
保存した物と現在の値が10以上ひらいたら,
という風に変更したら,まずは,動きました。
それとTRさんのプログラは,最初から完成形,みたいに,
必要なこと全部盛ってるような気がします。
全部盛り込んで,不具合を修正するやり方もあると思います。
なかなか,不具合見つけるの大変だと思います。
私は,逆のやり方で,必要なことを一つ一つ確認して,
全体を仕上げていく感じでやってます。
取り合えず動作の確認できた,私のプログラムです。
電圧の変化に応じて,U/Dの動作を
UP→LED点灯
DOWN→消灯
で,
INCを100mvではなく,10mvの変化で一回点滅,
ということで,確かめました。
下記がそのプログラムですが,ちょっと猛牛ロックさんの前では,
恥ずかしいです。
while(1){
setADCChannel(0); // A/D変換対象チャンネルを設定
buffer = readADCValue(); // A/D変換値を取得
itoa(str,hozon,10);
lcd_clear(); //表示クリア
lcd_setCursor(0, 0);
lcd_puts(str);
lcd_puts("mV");
__delay_us(50);
if(abs((buffer-hozon))>10){
newhozon=buffer;
itoa(str1,newhozon,10);
lcd_setCursor(0, 1);
lcd_puts(str1);
lcd_puts("mV");
if( hozon > newhozon ){
U_D=HIGHT;
increse((hozon-newhozon)/10);
}
if( newhozon > hozon ){
U_D=LOW;
increse((newhozon-hozon)/10);
}
hozon=newhozon;
}
}
}
void increse(int ohom){
int i;
for(i=0;i<ohom;i++){
INC=LOW;
__delay_ms(100);
INC=HIGHT;
__delay_ms(1000);
}
}
すっきりとしたプログラムありがとうございます。
多分,実際の使用を想定しプログラムですね。
私は,今,タイミングチャートは,ちょっと,度外視してます。
for(char i=0;i<4;i++)target+=adc[i];
target/=40.9;
部分は,移動平均でしょうか。
私がもがいてるのは,その前の段階で,動作をLED,LCDで,確認している段階です。
とりあえず,U/DとINCの2本の線の動作を頭においてます。
実際使うとなると,ワイパーの保持とか,ワイパーの閾値の処理とか,まだ未知の部分が多いので,とりあえずはというところです。
それから,
>その場合は反応の遅さとして表れます。どの位が適しているかは、Machからの信号の周波数が元になります。
>私の好みとしてはデジタルでそのまま読み取る方法かなぁ。
そうですね。デジタルを直接読み取るには,ちょっとプログラム組まないとですね。
PWMの基本周波数の変換のプログラムを移植しましたが,
理解するのに時間かかって,手こずりました。
その点,アナログでの受け取りは,反応速度の問題もあるでしょけど,ADCで読み取れるので,お手軽でしょうかね。
それと,MACHで,RPMの情報は,直接でてるのでしょうか。
ただ,RPMの情報あったとしても,それをもとにコントロールするとなると,PIDの調整等が必要でしょうから,
ちょっとハードルたかいかな,なんて思います。
>現在が何rpm出ているのかを取得しないと、プログラムを繋げようがないです。
>或いは、適当にrpmを100段階(抵抗の分解能)にしようとしているのでしょうか?
私個人は,とりあえず,10段階ぐらいの範囲で,スピードが
調整できればいいかなと思いました。
TRさん,こんばんは。
1514でも書きましたが,
if (hozon != adconv())
がだめでした。
ここを
if(abs((buffer-hozon))>10)
保存した物と現在の値が10以上ひらいたら,
という風に変更したら,まずは,動きました。
それとTRさんのプログラは,最初から完成形,みたいに,
必要なこと全部盛ってるような気がします。
全部盛り込んで,不具合を修正するやり方もあると思います。
なかなか,不具合見つけるの大変だと思います。
私は,逆のやり方で,必要なことを一つ一つ確認して,
全体を仕上げていく感じでやってます。
取り合えず動作の確認できた,私のプログラムです。
電圧の変化に応じて,U/Dの動作を
UP→LED点灯
DOWN→消灯
で,
INCを100mvではなく,10mvの変化で一回点滅,
ということで,確かめました。
下記がそのプログラムですが,ちょっと猛牛ロックさんの前では,
恥ずかしいです。
while(1){
setADCChannel(0); // A/D変換対象チャンネルを設定
buffer = readADCValue(); // A/D変換値を取得
itoa(str,hozon,10);
lcd_clear(); //表示クリア
lcd_setCursor(0, 0);
lcd_puts(str);
lcd_puts("mV");
__delay_us(50);
if(abs((buffer-hozon))>10){
newhozon=buffer;
itoa(str1,newhozon,10);
lcd_setCursor(0, 1);
lcd_puts(str1);
lcd_puts("mV");
if( hozon > newhozon ){
U_D=HIGHT;
increse((hozon-newhozon)/10);
}
if( newhozon > hozon ){
U_D=LOW;
increse((newhozon-hozon)/10);
}
hozon=newhozon;
}
}
}
void increse(int ohom){
int i;
for(i=0;i<ohom;i++){
INC=LOW;
__delay_ms(100);
INC=HIGHT;
__delay_ms(1000);
}
}
Re: 続続続ーPWM
プログラムの中で「ワイパー位置」を基準(意識したもの)にした方が良いです。
このプログラムではADC値(1024分割)が基準になっていて、ワイパー(100分割)の位置が意識されていません。
X9Cは操作は簡単と言えますけど、絶対位置が無いのでワイパー位置は自分で管理する必要があります。
(現在、ポテンショメータの両端を行き来するような動きになると思います)
その辺りは絶対位置で指定できるタイプの方が簡単です。
→初期化(0もしくはMAXの位置を割り出)して、記憶させる必要があります。
で、根本的な事になるのですけど、
10kHz程度で分解能が確保できるのなら、フィルターからそのままスピンドル入力に入れられないのでしょうか?
10Hzや100HzならPICで処理した方が良いでしょうけど。でもその場合はデジタルで入力した方が面倒じゃないと思います。
MABOさんの方はデジタル入力ですよね。
MACHは実際の回転数を入れると調整してくれるのですか?知らなかったです。
そっちの方の感想も書いておきます。
・割り込みで利用する外部変数にはvolatileを付けておいた方が良い。
・スピンドル停止時の処理はTIMER0を使っているけど、現在の8ms(だと思う)は
不適当。テスト期間中は0.2sぐらいにしておいた方がMACHを弄りやすい。
※わざわざTIMER0を使わなくても、TIMER2割り込み内で、
pwmPeriodCounter++;//の後に
if(pwmPeriodCounter>2000)zero_pwm();
とか。
・現在、100usでサンプリングしていますけど、総カウント値を読み取った方が良いです。
勿論、タイマー2はPWMと併用しているのでタイマー2をリセットするわけにはいきません。
外部割り込み時にタイマー値を保存して、何回回ったかを加味して、算出します。
※使っていないタイマー1を利用した方が、タイマー自体をリセットできるので楽。
このプログラムではADC値(1024分割)が基準になっていて、ワイパー(100分割)の位置が意識されていません。
X9Cは操作は簡単と言えますけど、絶対位置が無いのでワイパー位置は自分で管理する必要があります。
(現在、ポテンショメータの両端を行き来するような動きになると思います)
その辺りは絶対位置で指定できるタイプの方が簡単です。
→初期化(0もしくはMAXの位置を割り出)して、記憶させる必要があります。
で、根本的な事になるのですけど、
10kHz程度で分解能が確保できるのなら、フィルターからそのままスピンドル入力に入れられないのでしょうか?
10Hzや100HzならPICで処理した方が良いでしょうけど。でもその場合はデジタルで入力した方が面倒じゃないと思います。
MABOさんの方はデジタル入力ですよね。
MACHは実際の回転数を入れると調整してくれるのですか?知らなかったです。
そっちの方の感想も書いておきます。
・割り込みで利用する外部変数にはvolatileを付けておいた方が良い。
・スピンドル停止時の処理はTIMER0を使っているけど、現在の8ms(だと思う)は
不適当。テスト期間中は0.2sぐらいにしておいた方がMACHを弄りやすい。
※わざわざTIMER0を使わなくても、TIMER2割り込み内で、
pwmPeriodCounter++;//の後に
if(pwmPeriodCounter>2000)zero_pwm();
とか。
・現在、100usでサンプリングしていますけど、総カウント値を読み取った方が良いです。
勿論、タイマー2はPWMと併用しているのでタイマー2をリセットするわけにはいきません。
外部割り込み時にタイマー値を保存して、何回回ったかを加味して、算出します。
※使っていないタイマー1を利用した方が、タイマー自体をリセットできるので楽。
Re: 続続続ーPWM
maboさんへ、
>if(abs((buffer-hozon))>10)
保存した物と現在の値が10以上ひらいたら,
という風に変更したら,まずは,動きました。
ご教授いただいた部分を自分なりに変えました。
8行目です。
でも、まったくモニター用LEDが反応しません。((+_+))
1 // ADコンバータ設定
2 ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
3 ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
4
5 while (1) {
6 hozon = adconv(); // A/D変換対象チャンネルを設定
7 __delay_us(50);
8 if (abs(hozon - adconv())>10) {
9 newhozon = adconv();
10 if (abs(hozon-newhozon)<= 10) {
11 newhozon = hozon;
12 if ((hozon > newhozon)>10) {
13 RA3 = 1;
14 increse((hozon - newhozon) / 10);
15 }
16 if ((newhozon > hozon)>10) {
17 RA3 = 0;
18 increse((newhozon - hozon) / 10);
19 }
20 hozon = newhozon;
21 }
22 }
23 }
24 }
25 //増減をカウント関数
26 void increse(int ohom) {
27 int i;
28 for (i = 0; i < ohom; i++) {
29 RA1 = 0;
30 __delay_ms(100);
31 RA1 = 1;
32 __delay_ms(1000);
33 }
34 }
35
36 // アナログ値の変換と読込み処理関数
37 unsigned int adconv(void) {
38 GO_nDONE = 1; // アナログ値読取り開始指示
39 while (GO_nDONE); // 読取り完了まで待つ
40 return ADRES;
41 }
>if(abs((buffer-hozon))>10)
保存した物と現在の値が10以上ひらいたら,
という風に変更したら,まずは,動きました。
ご教授いただいた部分を自分なりに変えました。
8行目です。
でも、まったくモニター用LEDが反応しません。((+_+))
1 // ADコンバータ設定
2 ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
3 ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
4
5 while (1) {
6 hozon = adconv(); // A/D変換対象チャンネルを設定
7 __delay_us(50);
8 if (abs(hozon - adconv())>10) {
9 newhozon = adconv();
10 if (abs(hozon-newhozon)<= 10) {
11 newhozon = hozon;
12 if ((hozon > newhozon)>10) {
13 RA3 = 1;
14 increse((hozon - newhozon) / 10);
15 }
16 if ((newhozon > hozon)>10) {
17 RA3 = 0;
18 increse((newhozon - hozon) / 10);
19 }
20 hozon = newhozon;
21 }
22 }
23 }
24 }
25 //増減をカウント関数
26 void increse(int ohom) {
27 int i;
28 for (i = 0; i < ohom; i++) {
29 RA1 = 0;
30 __delay_ms(100);
31 RA1 = 1;
32 __delay_ms(1000);
33 }
34 }
35
36 // アナログ値の変換と読込み処理関数
37 unsigned int adconv(void) {
38 GO_nDONE = 1; // アナログ値読取り開始指示
39 while (GO_nDONE); // 読取り完了まで待つ
40 return ADRES;
41 }
Re: 続続続ーPWM
猛牛ロックさんへ
レスが遅くなってすみません。
外部変数なんて聞いたことがないので、まったく反応ができません。
それでも、少し見ましたが、断念。
今は、この状態です。
No1518について
>
このプログラムではADC値(1024分割)が基準になっていて、ワイパー(100分割)の位置が意識されていません。
X9Cは操作は簡単と言えますけど、絶対位置が無いのでワイパー位置は自分で管理する必要があります。
(現在、ポテンショメータの両端を行き来するような動きになると思います)
その辺りは絶対位置で指定できるタイプの方が簡単です。
なるほどなと思います。
具体的には、No1515中にその記載があるのでしょうか?
レスが遅くなってすみません。
外部変数なんて聞いたことがないので、まったく反応ができません。
それでも、少し見ましたが、断念。
今は、この状態です。
No1518について
>
このプログラムではADC値(1024分割)が基準になっていて、ワイパー(100分割)の位置が意識されていません。
X9Cは操作は簡単と言えますけど、絶対位置が無いのでワイパー位置は自分で管理する必要があります。
(現在、ポテンショメータの両端を行き来するような動きになると思います)
その辺りは絶対位置で指定できるタイプの方が簡単です。
なるほどなと思います。
具体的には、No1515中にその記載があるのでしょうか?
Re: 続続続ーPWM
外部変数は、関数外に書いてある変数です。グローバル変数と同じです。
> //外部変数
> volatile char x9c_val;
このx9c_valという変数自体がワイパー位置です。X9C VALUE(X9Cの値)です。
どの関数からも操作可能にします。
その次に書いてある
> void x9c_init(void)
これが初期化関数です。
99回ワイパーをダウンさせて確実に0の位置まで移動してx9c_valを0にします。
なので、while(1)の直前に1回実行させます。
> void x9c_up(void)
> void x9c_dowm(void){
名前の通り、UPやDOWNさせる関数です。1つだけ移動させます。
関数内でx9c_valも変化させています。
場合によっては限界位置を超えた操作をしている、という戻り値を付けても良いです。
MABOさんのように複数回上下させる関数も考えましたけど、1つ動かすの500us以上間隔をあける
必要があるらしいので、その手法は止めました。
つまり、数usで新たな値が取得できるのに、500×回数分の時間を割くことも無い、という判断です。
あとはこっちの方がノイズ等に強い=反応が鈍いと思います。
No1518の
> (現在、ポテンショメータの両端を行き来するような動きになると思います)
これは勘違いでした。レンジ自体は/10になっていますね。
使っている内に使用範囲でまとまる気はします。でもちゃんと位置を把握したものにすべきです。
別件ですけど、No1516
> void increse(int ohom){
> int i;
> for(i=0;i<ohom;i++){
> INC=LOW;
> __delay_ms(100);
> INC=HIGHT;
> __delay_ms(1000);
> }
だと、ワイパーを20段階動かすのに22秒かかります。
これはMACHからの信号を受けてのテストですか?それとも可変抵抗でのテスト?
手元の可変抵抗ならいくらなんでも遅すぎかと思います。
ワイパーが移動完了するまでは可変抵抗の変化は受け付けません。
> //外部変数
> volatile char x9c_val;
このx9c_valという変数自体がワイパー位置です。X9C VALUE(X9Cの値)です。
どの関数からも操作可能にします。
その次に書いてある
> void x9c_init(void)
これが初期化関数です。
99回ワイパーをダウンさせて確実に0の位置まで移動してx9c_valを0にします。
なので、while(1)の直前に1回実行させます。
> void x9c_up(void)
> void x9c_dowm(void){
名前の通り、UPやDOWNさせる関数です。1つだけ移動させます。
関数内でx9c_valも変化させています。
場合によっては限界位置を超えた操作をしている、という戻り値を付けても良いです。
MABOさんのように複数回上下させる関数も考えましたけど、1つ動かすの500us以上間隔をあける
必要があるらしいので、その手法は止めました。
つまり、数usで新たな値が取得できるのに、500×回数分の時間を割くことも無い、という判断です。
あとはこっちの方がノイズ等に強い=反応が鈍いと思います。
No1518の
> (現在、ポテンショメータの両端を行き来するような動きになると思います)
これは勘違いでした。レンジ自体は/10になっていますね。
使っている内に使用範囲でまとまる気はします。でもちゃんと位置を把握したものにすべきです。
別件ですけど、No1516
> void increse(int ohom){
> int i;
> for(i=0;i<ohom;i++){
> INC=LOW;
> __delay_ms(100);
> INC=HIGHT;
> __delay_ms(1000);
> }
だと、ワイパーを20段階動かすのに22秒かかります。
これはMACHからの信号を受けてのテストですか?それとも可変抵抗でのテスト?
手元の可変抵抗ならいくらなんでも遅すぎかと思います。
ワイパーが移動完了するまでは可変抵抗の変化は受け付けません。
Re: 続続続ーPWM
猛牛ロックさんへ
>どの関数からも操作可能にします。
そうか、そういわれて、x9c_val=0とかが見えてきました。
こうして、0点に戻しているわけですよね?
以下のことについても、すみませんが、教えてください。
宜しくお願いします
01 //外部変数 −
02 volatile char x9c_val; −
03 −
04 void x9c_init(void) { − x9c_init関数は、何をしようとしているのですか?
05 ud = 0; −
06 for (char i = 0; i < 99; i++) { −
07 inc = 0; − なぜ、0と1にするのですか?
08 __delay_us(1); −
09 inc = 1; −
10 __delay_us(500); −
11 } −
12 x9c_val = 0; − 0ということは、この時点で、終了ということ?
13 } −
14 −
15 void x9c_up(void) { −
16 ud = 1; −
17 inc = 0; −
18 __delay_us(1); −
19 inc = 1; −
20 if (x9c_val < 99)x9c_val++; −
21 //次の上げ下げは500us空ける −
22 } −
23 −
24 void x9c_dowm(void) { − こ24〜31行目の間は、何をさせているのですか?
25 ud = 0; −
26 inc = 0; −
27 __delay_us(1); −
28 inc = 1; −
29 if (x9c_val > 0)x9c_val--; −
30 //次の上げ下げは500us空ける −
31 } −
32 −
33 void main() { −
34 −
35 //略 −
36 −
37 x9c_init(); −
38 while (1) { −
39 static unsigned int adc[4] = {0}; − adc[4]の意味?
40 static char num = 0; − numの意味?
41 unsigned int target = 0; −
42 adc[(++num)&3] = adconv(); −
43 for (char i = 0; i < 4; i++)target += adc[i]; − targetの意味?
44 target /= 40.9; −
45 −
46 if (target > x9c_val)x9c_up(); −
47 else if (target < x9c_val)x9c_down(); −
48 _delay_ms(1); −
49 } −
50 } −
>どの関数からも操作可能にします。
そうか、そういわれて、x9c_val=0とかが見えてきました。
こうして、0点に戻しているわけですよね?
以下のことについても、すみませんが、教えてください。
宜しくお願いします
01 //外部変数 −
02 volatile char x9c_val; −
03 −
04 void x9c_init(void) { − x9c_init関数は、何をしようとしているのですか?
05 ud = 0; −
06 for (char i = 0; i < 99; i++) { −
07 inc = 0; − なぜ、0と1にするのですか?
08 __delay_us(1); −
09 inc = 1; −
10 __delay_us(500); −
11 } −
12 x9c_val = 0; − 0ということは、この時点で、終了ということ?
13 } −
14 −
15 void x9c_up(void) { −
16 ud = 1; −
17 inc = 0; −
18 __delay_us(1); −
19 inc = 1; −
20 if (x9c_val < 99)x9c_val++; −
21 //次の上げ下げは500us空ける −
22 } −
23 −
24 void x9c_dowm(void) { − こ24〜31行目の間は、何をさせているのですか?
25 ud = 0; −
26 inc = 0; −
27 __delay_us(1); −
28 inc = 1; −
29 if (x9c_val > 0)x9c_val--; −
30 //次の上げ下げは500us空ける −
31 } −
32 −
33 void main() { −
34 −
35 //略 −
36 −
37 x9c_init(); −
38 while (1) { −
39 static unsigned int adc[4] = {0}; − adc[4]の意味?
40 static char num = 0; − numの意味?
41 unsigned int target = 0; −
42 adc[(++num)&3] = adconv(); −
43 for (char i = 0; i < 4; i++)target += adc[i]; − targetの意味?
44 target /= 40.9; −
45 −
46 if (target > x9c_val)x9c_up(); −
47 else if (target < x9c_val)x9c_down(); −
48 _delay_ms(1); −
49 } −
50 } −
Re: 続続続ーPWM
> x9c_init関数は、何をしようとしているのですか?
デバイスの初期化です。このデバイスはスタート位置がありません。
(CSピンを操作して起動する位置を決める=保存する事は可能です。)
なので、99回ワイパー位置を下げて、0の位置まで持ってきて、その位置を0にしています。
> 24〜31行目の間は、何をさせているのですか?
x9c_up() →位置を1つ上げる関数
x9c_down()→位置を1つ下げる関数
です。やってる事はudピンを合わせて、クロックを入れています。
ワイパー位置が変化するので、その分、変数x9c_valも操作しています。
> adc[4]の意味?
> numの意味?
やっているのは4回分のADCサンプルを取って処理している、という事です。
デジタルをフィルターを通してアナログ化しているので、多少の波ができます。
4回といわず、倍の8回分位取った方がいいかも。
numはただの数です。回数を数えるために(++num)使っています。
> targetの意味?
ターゲット、目標値です。つまり、MACHからのPWM信号は(100分率で)この値が来ているので、
それになるようにx9cを操作する、という流れです。
デバイスの初期化です。このデバイスはスタート位置がありません。
(CSピンを操作して起動する位置を決める=保存する事は可能です。)
なので、99回ワイパー位置を下げて、0の位置まで持ってきて、その位置を0にしています。
> 24〜31行目の間は、何をさせているのですか?
x9c_up() →位置を1つ上げる関数
x9c_down()→位置を1つ下げる関数
です。やってる事はudピンを合わせて、クロックを入れています。
ワイパー位置が変化するので、その分、変数x9c_valも操作しています。
> adc[4]の意味?
> numの意味?
やっているのは4回分のADCサンプルを取って処理している、という事です。
デジタルをフィルターを通してアナログ化しているので、多少の波ができます。
4回といわず、倍の8回分位取った方がいいかも。
numはただの数です。回数を数えるために(++num)使っています。
> targetの意味?
ターゲット、目標値です。つまり、MACHからのPWM信号は(100分率で)この値が来ているので、
それになるようにx9cを操作する、という流れです。
Re: 続続続ーPWM
猛牛ロックさんへ
7〜9行目は、初期化のために7行目で一旦、0にし、1μs後に1としてHiにしてるのですか?
12行目も初期化の為に、x9c_valに0を代入しているのですか?
adc4は配列関数で、個数が4個あり、{}内に値を書くと思うのですが、0の1個だけでいいのですか?4個分の値を書かなくていいのですか?
44行目の40.9の算出方法を具体的に教えてくださいお願いします。
7〜9行目は、初期化のために7行目で一旦、0にし、1μs後に1としてHiにしてるのですか?
12行目も初期化の為に、x9c_valに0を代入しているのですか?
adc4は配列関数で、個数が4個あり、{}内に値を書くと思うのですが、0の1個だけでいいのですか?4個分の値を書かなくていいのですか?
44行目の40.9の算出方法を具体的に教えてくださいお願いします。
Re: 続続続ーPWM
> 7〜9行目は、初期化のために7行目で一旦、0にし、1μs後に1としてHiにしてるのですか?
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0; − 0ということは、この時点で、終了ということ?
}
初期化は、起動時にどの位置にワイパーがあるのか不明なので行います。
今回は普通に、0の位置にワイパーを移動させて初期化します。
Max位置の99まで上げて99に初期化しても良いです。
ワイパー位置を上げる場合は、udピンを1にして、クロック(incピンを↓でストローブ)を入れます。
下げる場合はudピンを0にして、クロックを入れます。
で、今回の目的は99回ワイパーを下げて、0の位置にしたのちに、その位置をx9c_valに記憶させます。
まず、
ud=0;
で下げるむきにしておいて、
for文で99回クロックを入れて、位置を99回下げています。
まぁ、起動時に10の位置で起動したら実際に行われるのは9回までで残り90回は無駄な動作ですけど、
最初の位置が判らないので仕方が無い処理です。
__delay_us(1); や__delay_us(500);はデバイスを動作させるのに必要な間隔です。
それ以上なら問題ありません。
> 12行目も初期化の為に、x9c_valに0を代入しているのですか?
そうです。絶対位置で指定できるデバイスならこれらの処理は必要ありません。
> adc[4]は配列関数で、個数が4個あり、{}内に値を書くと思うのですが
配列の初期化の方法の1つです。その記述ですべて0で初期化されます。
> 44行目の40.9の算出方法を具体的に教えてくださいお願いします。
その前に、adc[4]に入っている過去4回のデータを足しています。
つまり、最大値が1023*4=4092です。これが100分割になるように40.9で割っています。
※今気づきましたけど、最大値が99になるようにすべきですね。
なので、40.93で割った方が良いです。
void x9c_init(void) {
ud = 0;
for (char i = 0; i < 99; i++) {
inc = 0;
__delay_us(1);
inc = 1;
__delay_us(500);
}
x9c_val = 0; − 0ということは、この時点で、終了ということ?
}
初期化は、起動時にどの位置にワイパーがあるのか不明なので行います。
今回は普通に、0の位置にワイパーを移動させて初期化します。
Max位置の99まで上げて99に初期化しても良いです。
ワイパー位置を上げる場合は、udピンを1にして、クロック(incピンを↓でストローブ)を入れます。
下げる場合はudピンを0にして、クロックを入れます。
で、今回の目的は99回ワイパーを下げて、0の位置にしたのちに、その位置をx9c_valに記憶させます。
まず、
ud=0;
で下げるむきにしておいて、
for文で99回クロックを入れて、位置を99回下げています。
まぁ、起動時に10の位置で起動したら実際に行われるのは9回までで残り90回は無駄な動作ですけど、
最初の位置が判らないので仕方が無い処理です。
__delay_us(1); や__delay_us(500);はデバイスを動作させるのに必要な間隔です。
それ以上なら問題ありません。
> 12行目も初期化の為に、x9c_valに0を代入しているのですか?
そうです。絶対位置で指定できるデバイスならこれらの処理は必要ありません。
> adc[4]は配列関数で、個数が4個あり、{}内に値を書くと思うのですが
配列の初期化の方法の1つです。その記述ですべて0で初期化されます。
> 44行目の40.9の算出方法を具体的に教えてくださいお願いします。
その前に、adc[4]に入っている過去4回のデータを足しています。
つまり、最大値が1023*4=4092です。これが100分割になるように40.9で割っています。
※今気づきましたけど、最大値が99になるようにすべきですね。
なので、40.93で割った方が良いです。
Re: 続続続ーPWM
猛牛ロックさんへ
配列adcの{0}により、43行目の左辺が0(初期化)になるのでしょか?
0になるのは、targetですか?
でも、44行目と意味がつながらない。これでは、おかしいどうして?
42行目は、adcon()関数を実行して、その値をどうしようとしているのですか?[]の意味が分かりません??
察するに、46行目で、adc変換後の値(4回分の合計値)を40.9で割って、
出た値とx9c_valをif文の中でxpcをup/downの関数を呼び出しているわけでしょうか?
それとですが、
以下のように、adconv()関数をmain関数の後につけましたが、どうもうまくつながりません。どうしたらよいでしょうか?
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA0で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
配列adcの{0}により、43行目の左辺が0(初期化)になるのでしょか?
0になるのは、targetですか?
でも、44行目と意味がつながらない。これでは、おかしいどうして?
42行目は、adcon()関数を実行して、その値をどうしようとしているのですか?[]の意味が分かりません??
察するに、46行目で、adc変換後の値(4回分の合計値)を40.9で割って、
出た値とx9c_valをif文の中でxpcをup/downの関数を呼び出しているわけでしょうか?
それとですが、
以下のように、adconv()関数をmain関数の後につけましたが、どうもうまくつながりません。どうしたらよいでしょうか?
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA0で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
Re: 続続続ーPWM
TRさん,猛牛ロックさん,こんばんは。
横レスになってしまいますが,ご容赦を・・・・。
*********猛牛ロックさんへ*********
ーーー基本周波数の変更のプログラムについてーーーー
感想ありがとうございます。
このプログラムは,諸兄のプログラムを移植したもので,
オリジナルは私ではないので,理解するのに苦労しました。
ご指摘のように,TIMER0で,最初,8msで,
停止の処理してましたが,読み込む周波数が100hzで,
取りこぼしてたので,現在は,倍の16msにしたと思います。
サンプリングの方法については,いじると全体が,
おかしくなる可能性あるので,いじっていません。
オリジナルでないので,あまりいじりたくないなと,思ってます。
>MABOさんの方はデジタル入力ですよね。
>MACHは実際の回転数を入れると調整してくれるのですか?知らなかったです。
>そっちの方の感想も書いておきます。
デジタル入力ですが,デジタルポテンショメータも興味あって,弄り始めました。
MACHには,クローズドループ,ループバック等の設定もあります。
PIDの数値の入力もありますが,ここは,ちょっと分かりません。
チェックの有無で,私の環境では,大きな変化ありませんでした。
設定がまずいのかも。
−−−−−1516のプログラムについてーーーー
void increse(int ohom){
int i;
for(i=0;i<ohom;i++){
INC=LOW;
__delay_ms(100);
INC=HIGHT;
__delay_ms(1000);
}
ですが,これ,LEDの点滅で動作確認のため遅くしました。
実機がないので,こんなことで,目視で確認してます。
−−−−−デジタルポテンショメーターについてーーーー
初期化のことについては,猛牛ロックさんのおっしゃる通りだと思います。
ただ,途中のワイパーの動きをを保持(記憶)しなければ,
デフォルトに戻るのかな,なんて思ってました。
マニュアルから,デフォルトの設定読み取れなかったので,
もしかして,ワイパーは,10kΩだと40Ωのところがデフォルトかな,と邪推してました。
それから,ワイパーは,99じゃなくて,最大動けるのは,
98かもですね。
不確かですが,最大動かしても,「40Ω残る」 の記事が,
マニュアルにあったような。
一番端までは,いけないような気がします。
*****TRさんへ******
混乱すると申し訳ないので,
猛牛ロックさんの書いてくれたプログラムについては,
控えたいと思いますが,
下記のこと分かると,理解しやすいと思います。
A+=A
は,
A=A+1
と同じ意味で,表記方法が違うだけです。
私はこの書き方は苦手です。
http://www1.cts.ne.jp/~clab/hsample/Primary/Io11.html
それと,是非,LCD導入なさることおすすめします。
格段にデバックの効率あがります。
LCDの表示は,通常のものであれば,
それほど難しくはないと思います。
選ぶときは,インターフェースが,I2C以外のものの
方がと思います。
http://akizukidenshi.com/catalog/g/gP-00038/
あたりでしょうか。
横レスになってしまいますが,ご容赦を・・・・。
*********猛牛ロックさんへ*********
ーーー基本周波数の変更のプログラムについてーーーー
感想ありがとうございます。
このプログラムは,諸兄のプログラムを移植したもので,
オリジナルは私ではないので,理解するのに苦労しました。
ご指摘のように,TIMER0で,最初,8msで,
停止の処理してましたが,読み込む周波数が100hzで,
取りこぼしてたので,現在は,倍の16msにしたと思います。
サンプリングの方法については,いじると全体が,
おかしくなる可能性あるので,いじっていません。
オリジナルでないので,あまりいじりたくないなと,思ってます。
>MABOさんの方はデジタル入力ですよね。
>MACHは実際の回転数を入れると調整してくれるのですか?知らなかったです。
>そっちの方の感想も書いておきます。
デジタル入力ですが,デジタルポテンショメータも興味あって,弄り始めました。
MACHには,クローズドループ,ループバック等の設定もあります。
PIDの数値の入力もありますが,ここは,ちょっと分かりません。
チェックの有無で,私の環境では,大きな変化ありませんでした。
設定がまずいのかも。
−−−−−1516のプログラムについてーーーー
void increse(int ohom){
int i;
for(i=0;i<ohom;i++){
INC=LOW;
__delay_ms(100);
INC=HIGHT;
__delay_ms(1000);
}
ですが,これ,LEDの点滅で動作確認のため遅くしました。
実機がないので,こんなことで,目視で確認してます。
−−−−−デジタルポテンショメーターについてーーーー
初期化のことについては,猛牛ロックさんのおっしゃる通りだと思います。
ただ,途中のワイパーの動きをを保持(記憶)しなければ,
デフォルトに戻るのかな,なんて思ってました。
マニュアルから,デフォルトの設定読み取れなかったので,
もしかして,ワイパーは,10kΩだと40Ωのところがデフォルトかな,と邪推してました。
それから,ワイパーは,99じゃなくて,最大動けるのは,
98かもですね。
不確かですが,最大動かしても,「40Ω残る」 の記事が,
マニュアルにあったような。
一番端までは,いけないような気がします。
*****TRさんへ******
混乱すると申し訳ないので,
猛牛ロックさんの書いてくれたプログラムについては,
控えたいと思いますが,
下記のこと分かると,理解しやすいと思います。
A+=A
は,
A=A+1
と同じ意味で,表記方法が違うだけです。
私はこの書き方は苦手です。
http://www1.cts.ne.jp/~clab/hsample/Primary/Io11.html
それと,是非,LCD導入なさることおすすめします。
格段にデバックの効率あがります。
LCDの表示は,通常のものであれば,
それほど難しくはないと思います。
選ぶときは,インターフェースが,I2C以外のものの
方がと思います。
http://akizukidenshi.com/catalog/g/gP-00038/
あたりでしょうか。
続続ーPWM
TRさん,こんにちは。また,スレ深くなったの,新しくします。
今日は,PWMの基本周波数の変更のプログラムいじってました。
以前掲載したときは,HITECHのコンパイラ用でしたので,
XC8用に変更してました。
正直面倒くさいですね,新しいコンパイラ用に書き換えるのは。
さて,前掲のデジタルポテンショメータの使い方ですが,
使い方をのせていた諸兄は,Arduinoでプログラム組んでいるようですね。
多分,直接,SECさんの基板等との接続は難しいでしょうね。
でも,PWMの出力を使えば,コントロールはできそうに思います。
いくつか方法あると思いますけど,
MACHのPWM出力→→フィルターで直流変換→→
PICでAD変換→→PICで抵抗のUP・DOWN
と,できないことないかとは思いますけど,ちょっと時間かかりるかなあ。
PWMを直流で受けてAD変換したものを使ってる諸兄は,
下記です。
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
操作的には,2本の線のそれぞれをHIGHT LOWにするだけですから,PICでもそれほ難しくないと思います。
ただ,それよりも,AD変換した数値と設定抵抗等の関係,
いち調べるのに時間かかるかもですね。
今日は,PWMの基本周波数の変更のプログラムいじってました。
以前掲載したときは,HITECHのコンパイラ用でしたので,
XC8用に変更してました。
正直面倒くさいですね,新しいコンパイラ用に書き換えるのは。
さて,前掲のデジタルポテンショメータの使い方ですが,
使い方をのせていた諸兄は,Arduinoでプログラム組んでいるようですね。
多分,直接,SECさんの基板等との接続は難しいでしょうね。
でも,PWMの出力を使えば,コントロールはできそうに思います。
いくつか方法あると思いますけど,
MACHのPWM出力→→フィルターで直流変換→→
PICでAD変換→→PICで抵抗のUP・DOWN
と,できないことないかとは思いますけど,ちょっと時間かかりるかなあ。
PWMを直流で受けてAD変換したものを使ってる諸兄は,
下記です。
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
操作的には,2本の線のそれぞれをHIGHT LOWにするだけですから,PICでもそれほ難しくないと思います。
ただ,それよりも,AD変換した数値と設定抵抗等の関係,
いち調べるのに時間かかるかもですね。
Re: 続続ーPWM
maboさんこんばんは。
今日は仕事でした。 再雇用ですね。
>PWMの基本周波数の変更のプログラムいじってました。
弄っていたプログラムは、ご紹介くださった以下URLのプログラム(PWM周波数変換プログラムと呼ぶかな?)
ですか?
素早いですね!
このプログラムは、smoothsutepperから出るPWMの周波数を変えるというものですよね?
違いますか?
で、maboさんが、
>MACHのPWM出力→→フィルターで直流変換→→
PICでAD変換→→PICで抵抗のUP・DOWN
と,できないことないかとは思いますけど,ちょっと時間かかりるかなあ。
と言っているのは、
PWM変換プログラムの変換後のPWMのところを、→ PICでAD変換→→PICで抵抗のUP・DOWN
ということですか?
考えもつきませんでした。
PWMという、波形をRCフィルターを通すとアナログに戻るなんてびっくりでした。
>PWMを直流で受けてAD変換したものを使ってる諸兄は,
RCフィルターでアナログの電圧に戻し、アナログ電圧をPICのAD変換機能を使って更にPWM化するとは!!
でもでも、
>PICでAD変換→→PICで抵抗のUP・DOWN
こんなことって、PICで出来るのですか??
ワクワクしてきました。
キットで遊ぼうのレベルです。 本にそういった方法はありましたか?
今日は仕事でした。 再雇用ですね。
>PWMの基本周波数の変更のプログラムいじってました。
弄っていたプログラムは、ご紹介くださった以下URLのプログラム(PWM周波数変換プログラムと呼ぶかな?)
ですか?
素早いですね!
このプログラムは、smoothsutepperから出るPWMの周波数を変えるというものですよね?
違いますか?
で、maboさんが、
>MACHのPWM出力→→フィルターで直流変換→→
PICでAD変換→→PICで抵抗のUP・DOWN
と,できないことないかとは思いますけど,ちょっと時間かかりるかなあ。
と言っているのは、
PWM変換プログラムの変換後のPWMのところを、→ PICでAD変換→→PICで抵抗のUP・DOWN
ということですか?
考えもつきませんでした。
PWMという、波形をRCフィルターを通すとアナログに戻るなんてびっくりでした。
>PWMを直流で受けてAD変換したものを使ってる諸兄は,
RCフィルターでアナログの電圧に戻し、アナログ電圧をPICのAD変換機能を使って更にPWM化するとは!!
でもでも、
>PICでAD変換→→PICで抵抗のUP・DOWN
こんなことって、PICで出来るのですか??
ワクワクしてきました。
キットで遊ぼうのレベルです。 本にそういった方法はありましたか?
Re: 続続ーPWM
TRさん,こんばんは。
>>PICでAD変換→→PICで抵抗のUP・DOWN
>こんなことって、PICで出来るのですか??
紹介したデジタルポテンショメータがつかえるのであれば,
2本の線をHIGHT・LOWにするだけですから,
キットで遊ぼうのLチカとそれほど変わらないと思います。
やることは,
(1)AD変換の数値をPICで受け取る
↓
(2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
↓
(5)数値が変化or変化しない
↓ ↓
↓ (1)へ
二つの端子の操作
↓
(1)
みたいな感じですかね。
これと同じようなことやるのに,
デジタルポテンショメーターの代わりに,LEDを二つ使って,
疑似の回路とプログラム作れると思います。
具体的には,
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html
と同じプログラムと同じ回路で,LEDを一つ増やして,
読み込んだ,AD変換の数値で,保存した数値の比較して,
数値が多くなったら,AのLEDをつけて消す,
数値が少なくなったら,BのLEDをつけて消す。
ということができれば,大丈夫でしょうね。
このプログラムで使ってるPWMはつかいませんので,もっと簡単になると思います。
実際の運用では,もうちょっと,考慮しなければいけないことあると思いますが,
ボリュームの部分をMACHからのアナログ変換したPWM信号へ,LEDの部分をデジタルポテンショメーターのアップダウンの端子へ,
ということで,キットで遊ぼうと同じよようなレベルで可能だと思います。
TRさんのお手持ちの材料でできますよ。
PICはAD変換の機能があるのならなんでもいいかな。
>>PICでAD変換→→PICで抵抗のUP・DOWN
>こんなことって、PICで出来るのですか??
紹介したデジタルポテンショメータがつかえるのであれば,
2本の線をHIGHT・LOWにするだけですから,
キットで遊ぼうのLチカとそれほど変わらないと思います。
やることは,
(1)AD変換の数値をPICで受け取る
↓
(2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
↓
(5)数値が変化or変化しない
↓ ↓
↓ (1)へ
二つの端子の操作
↓
(1)
みたいな感じですかね。
これと同じようなことやるのに,
デジタルポテンショメーターの代わりに,LEDを二つ使って,
疑似の回路とプログラム作れると思います。
具体的には,
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html
と同じプログラムと同じ回路で,LEDを一つ増やして,
読み込んだ,AD変換の数値で,保存した数値の比較して,
数値が多くなったら,AのLEDをつけて消す,
数値が少なくなったら,BのLEDをつけて消す。
ということができれば,大丈夫でしょうね。
このプログラムで使ってるPWMはつかいませんので,もっと簡単になると思います。
実際の運用では,もうちょっと,考慮しなければいけないことあると思いますが,
ボリュームの部分をMACHからのアナログ変換したPWM信号へ,LEDの部分をデジタルポテンショメーターのアップダウンの端子へ,
ということで,キットで遊ぼうと同じよようなレベルで可能だと思います。
TRさんのお手持ちの材料でできますよ。
PICはAD変換の機能があるのならなんでもいいかな。
Re: 続続ーPWM
maboさん、おはようございます。
いいですね、グットアイディアですね。
> (2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
●●●・・・
この肝となる部分をどうプログラムするのでしょうか?
幸いにも、以前、ここで、クーラントポンプを可変VRで制御するC言語を教えていただいたので、
これを基礎に頑張りたいと思います。
どうか、ご教授願います。
いいですね、グットアイディアですね。
> (2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
●●●・・・
この肝となる部分をどうプログラムするのでしょうか?
幸いにも、以前、ここで、クーラントポンプを可変VRで制御するC言語を教えていただいたので、
これを基礎に頑張りたいと思います。
どうか、ご教授願います。
Re: 続続ーPWM
TRさん,おはようございます。
今日の夜から泊まりがけで,ちょっと遠出しますので,
レス時間空くと思います。
具体的なプログラムですが,
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html
のプログラムの
while(1){
setADCChannel(0);
__delay_us(50);
duty1 = readADCValue();
setPWM1Duty(duty1);
}
コメントは外してありますが,ここを次のようにいじれば,
とりあえずは形になると思います。
具体的には,
int hozon=1024;
int newhozon=1024;
while(1){
setADCChannel(0);
__delay_us(50);
if(hozon ≠ readADCValue()){
newhozon=readADCValue();
RB2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
if((hozon-newhozon)>0)
RB3=1;//U/Dピンをアップに設定
increse();
}
if((hozon-newhozon)<0)
RB3=0;//U/Dピンをダウンに設定
increse();
}
RB2=1;//メモリー書き込み
}
}
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
}
AD変換で受け取る数値は,多分0〜1024ぐらいでしょうから,
これを10段階ぐらいに分けて,それに応じて,アップダウン
するという感じです。
実装するには,いろいろ考えないとだめだと思います。
AD変換の受け取り方は,
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
の方のように平均をとる必要があるかもしれません。
それから,デジタルポテンショメーターの操作で,
どのくらいの信号を送ればいいのか,
一回の操作で抵抗はどの程度変化するのか,
実験かデータシート等で確認する必要があると思います。
===追伸===
諸兄のデータ見たら,3本の線のコントロール必要ですね。
LEDは,二つ増やす必要ありですね。
今日の夜から泊まりがけで,ちょっと遠出しますので,
レス時間空くと思います。
具体的なプログラムですが,
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html
のプログラムの
while(1){
setADCChannel(0);
__delay_us(50);
duty1 = readADCValue();
setPWM1Duty(duty1);
}
コメントは外してありますが,ここを次のようにいじれば,
とりあえずは形になると思います。
具体的には,
int hozon=1024;
int newhozon=1024;
while(1){
setADCChannel(0);
__delay_us(50);
if(hozon ≠ readADCValue()){
newhozon=readADCValue();
RB2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
if((hozon-newhozon)>0)
RB3=1;//U/Dピンをアップに設定
increse();
}
if((hozon-newhozon)<0)
RB3=0;//U/Dピンをダウンに設定
increse();
}
RB2=1;//メモリー書き込み
}
}
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
}
AD変換で受け取る数値は,多分0〜1024ぐらいでしょうから,
これを10段階ぐらいに分けて,それに応じて,アップダウン
するという感じです。
実装するには,いろいろ考えないとだめだと思います。
AD変換の受け取り方は,
http://www002.upp.so-net.ne.jp/hard-and-soft/Spindol_Control/Spindol_Control.html
の方のように平均をとる必要があるかもしれません。
それから,デジタルポテンショメーターの操作で,
どのくらいの信号を送ればいいのか,
一回の操作で抵抗はどの程度変化するのか,
実験かデータシート等で確認する必要があると思います。
===追伸===
諸兄のデータ見たら,3本の線のコントロール必要ですね。
LEDは,二つ増やす必要ありですね。
Re: 続続ーPWM
maboさん、ありがとうございます。
お出かけということですね。
よく読んでみます。分からない点が多々出てくると思います。
その節は勘弁してください。
気をつけてお出かけください。
追記
ところで、このプログラムに使っているPICは16F88ですか?
教えてください。
お出かけということですね。
よく読んでみます。分からない点が多々出てくると思います。
その節は勘弁してください。
気をつけてお出かけください。
追記
ところで、このプログラムに使っているPICは16F88ですか?
教えてください。
Re: 続続ーPWM
TRさん,こんばんは。
レス遅くなりました。
はい,使ってるのは,16F88です。
でも,AD変換のあるものなら,
何でもいいと思います。
できれば,新しいのがいいかも。
16F88では,PICKIT 4は使えません。
もう,サポートの対象からはずれたんでしょうね。
いろいろ部品が届いてるので,
また,ぼちぼちやります。
レス遅くなりました。
はい,使ってるのは,16F88です。
でも,AD変換のあるものなら,
何でもいいと思います。
できれば,新しいのがいいかも。
16F88では,PICKIT 4は使えません。
もう,サポートの対象からはずれたんでしょうね。
いろいろ部品が届いてるので,
また,ぼちぼちやります。
Re: 続続ーPWM
maboさんこんにちは。
鉄ちゃん
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html?m=1
プログラム中程にある
次の事の意味分かりますか?
duty1 = readADCValue();
空のカッコ、こういった使い方は、初めてです?
お願いします。
鉄ちゃん
https://keitetsu.blogspot.com/2014/11/16f88-xc8-led.html?m=1
プログラム中程にある
次の事の意味分かりますか?
duty1 = readADCValue();
空のカッコ、こういった使い方は、初めてです?
お願いします。
Re: 続続ーPWM
TRさん,こんばんは。
サブ関数に以下のようにあります。
unsigned int readADCValue(void)
{
GO_nDONE = 0b1;
while(GO_nDONE);
return ((ADRESH << 8) + ADRESL);
}
括弧のなかが void になっていますので,
因数に何も渡さないの意味になります。
何も書かないのと同じ意味です。
unsigned int readADCValue(void)
を,
unsigned int readADCValue( )
と書いてもも同じです。
duty1 = readADCValue();
ですが,
これは,AD変換で,抵抗値を読みとった値を,
duty1
に代入の意味です。
サブ関数に以下のようにあります。
unsigned int readADCValue(void)
{
GO_nDONE = 0b1;
while(GO_nDONE);
return ((ADRESH << 8) + ADRESL);
}
括弧のなかが void になっていますので,
因数に何も渡さないの意味になります。
何も書かないのと同じ意味です。
unsigned int readADCValue(void)
を,
unsigned int readADCValue( )
と書いてもも同じです。
duty1 = readADCValue();
ですが,
これは,AD変換で,抵抗値を読みとった値を,
duty1
に代入の意味です。
Re: 続続ーPWM
鉄ちゃんおプログラムは何をしようとしているのでしょうか?
題目には、
可変抵抗(RA0)でLEDの輝度(RB3)を制御する
とありますが、
AD変換をした値(duty1)をPWMを発生させていますが、
duty1 = 0;
として、初期化をしたのち、
duty1 = readADCValue(); // A/D変換値を取得
とか、 setPWM1Duty(0);
とか、関数を作って複雑化しているように思えます。
自分も、以前、可変抵抗の電圧を読み取って、読んだ値を
ADRESに格納し、ADRESの値を使って、PWMを発生させましたが、
もっと単純だったはずなのにです。
デジタル抵抗と何か関係がるのでしょうか?
題目には、
可変抵抗(RA0)でLEDの輝度(RB3)を制御する
とありますが、
AD変換をした値(duty1)をPWMを発生させていますが、
duty1 = 0;
として、初期化をしたのち、
duty1 = readADCValue(); // A/D変換値を取得
とか、 setPWM1Duty(0);
とか、関数を作って複雑化しているように思えます。
自分も、以前、可変抵抗の電圧を読み取って、読んだ値を
ADRESに格納し、ADRESの値を使って、PWMを発生させましたが、
もっと単純だったはずなのにです。
デジタル抵抗と何か関係がるのでしょうか?
Re: 続続ーPWM
TRさん,こんばんは。
>デジタル抵抗と何か関係がるのでしょうか?
ですが,鉄ちゃんさんのプログラム,
一部分を改変すれば,デジタルポテンショメータのコントロール
に使えそうだ,
ということで,ご紹介しました。
使うのは,AD変換の部分で,PWMの部分はつかいませんが。
考え方として,鉄ちゃんさんの main() の
while(1)の部分を,1489のスレのように書き換えれば,
LEDを合計3つ使って,デジタルポテンショメータの実機がなくても,
シュミレートできそうです,ということでの紹介でした。
同じ,一つのことをするプログラムにも,多分,いくつかの書き方があるように思います。
>デジタル抵抗と何か関係がるのでしょうか?
ですが,鉄ちゃんさんのプログラム,
一部分を改変すれば,デジタルポテンショメータのコントロール
に使えそうだ,
ということで,ご紹介しました。
使うのは,AD変換の部分で,PWMの部分はつかいませんが。
考え方として,鉄ちゃんさんの main() の
while(1)の部分を,1489のスレのように書き換えれば,
LEDを合計3つ使って,デジタルポテンショメータの実機がなくても,
シュミレートできそうです,ということでの紹介でした。
同じ,一つのことをするプログラムにも,多分,いくつかの書き方があるように思います。
Re: 続続ーPWM
maboさん、おはようございます。
No1487の以下の内容は、鉄ちゃんのプログラムでいうとどの部分になりますか?
******
(1)AD変換の数値をPICで受け取る
↓
(2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
↓
(5)数値が変化or変化しない
******
追記
今回は、
電圧読み取りの変化の確認は、タイマー0割込みですかね〜?
No1487の以下の内容は、鉄ちゃんのプログラムでいうとどの部分になりますか?
******
(1)AD変換の数値をPICで受け取る
↓
(2)数値を保存
↓
(3)AD変換の数値をPICで再び受け取る
↓
(4)前回保存した数値と比較する
↓
(5)数値が変化or変化しない
******
追記
今回は、
電圧読み取りの変化の確認は、タイマー0割込みですかね〜?
Re: 続続ーPWM
maboさんすみません。
次の意味を教えてください。
void setADCChannel(unsigned char channel)
{
ADCON0 &= 0b11000111; // bit5~3,CHS<2:0>を初期化(電圧読み取りピンRA0設定だが&=により000)
ADCON0 |= (channel << 3);//上で初期化後、3bit左にシフト?
次の意味を教えてください。
void setADCChannel(unsigned char channel)
{
ADCON0 &= 0b11000111; // bit5~3,CHS<2:0>を初期化(電圧読み取りピンRA0設定だが&=により000)
ADCON0 |= (channel << 3);//上で初期化後、3bit左にシフト?
Re: 続続ーPWM
TRさんこんにちは。
おたずねの件ですが,次のような感じです。
間違いあるかもしれませんが。
コメントみてください。
int hozon=1024;
int newhozon=1024;
while(1){
setADCChannel(0);//読み込みチャンネルの設定
__delay_us(50);
if(hozon ≠ readADCValue()){//データを読み込んで保存データと読み込みデータの比較
newhozon=readADCValue();//保存したデータと違ったら保存
RB2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
//以下の部分で,変化に応じた処理
if((hozon-newhozon)>0)
RB3=1;//U/Dピンをアップに設定
increse();//ボリュームを移動
}
if((hozon-newhozon)<0)
RB3=0;//U/Dピンをダウンに設定
increse();//ボリュームを移動
}
RB2=1;//メモリー書き込み
}
}
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
みたいな感じで,while(1)の中で,読み取り,比較,処理
をしてます。
それから,
void setADCChannel(unsigned char channel)
{
ADCON0 &= 0b11000111; // bit5~3,CHS<2:0>を初期化(電圧読み取りピンRA0設定だが&=により000)
ADCON0 |= (channel << 3);//上で初期化後、3bit左にシフト?
ですが,ADCON0 の4ビット目から6ビットで,読み取りチャンネルの設定をするために,
&をとって,4〜6ビット目をにしてます。
ADCON0 |= (channel << 3)
は,読み取りチャンネルを channel で受けとって,
ADCON0 の4〜6ビット目にセットするために,
左に,3つシフトさせてます。
それから,AD変換では,割り込みを使う方法もあるようですが,
鉄ちゃんさんのプログラムで,AD変換では,割り込みは使ってないようです。
おたずねの件ですが,次のような感じです。
間違いあるかもしれませんが。
コメントみてください。
int hozon=1024;
int newhozon=1024;
while(1){
setADCChannel(0);//読み込みチャンネルの設定
__delay_us(50);
if(hozon ≠ readADCValue()){//データを読み込んで保存データと読み込みデータの比較
newhozon=readADCValue();//保存したデータと違ったら保存
RB2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
//以下の部分で,変化に応じた処理
if((hozon-newhozon)>0)
RB3=1;//U/Dピンをアップに設定
increse();//ボリュームを移動
}
if((hozon-newhozon)<0)
RB3=0;//U/Dピンをダウンに設定
increse();//ボリュームを移動
}
RB2=1;//メモリー書き込み
}
}
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
みたいな感じで,while(1)の中で,読み取り,比較,処理
をしてます。
それから,
void setADCChannel(unsigned char channel)
{
ADCON0 &= 0b11000111; // bit5~3,CHS<2:0>を初期化(電圧読み取りピンRA0設定だが&=により000)
ADCON0 |= (channel << 3);//上で初期化後、3bit左にシフト?
ですが,ADCON0 の4ビット目から6ビットで,読み取りチャンネルの設定をするために,
&をとって,4〜6ビット目をにしてます。
ADCON0 |= (channel << 3)
は,読み取りチャンネルを channel で受けとって,
ADCON0 の4〜6ビット目にセットするために,
左に,3つシフトさせてます。
それから,AD変換では,割り込みを使う方法もあるようですが,
鉄ちゃんさんのプログラムで,AD変換では,割り込みは使ってないようです。
Re: 続続ーPWM
Re: 続続ーPWM
setADCChannel(0);
この関数は、ADコンバーターの設定をすれば、不用?
理由
読み取り端子は固定なので。
for(i=0;i<abs((hozon-newhozon)/100));i++){
100で割る意味?
increse();
この関数の使い方?スケッチの書き方?
この関数は、ADコンバーターの設定をすれば、不用?
理由
読み取り端子は固定なので。
for(i=0;i<abs((hozon-newhozon)/100));i++){
100で割る意味?
increse();
この関数の使い方?スケッチの書き方?
Re: 続続ーPWM
increas();この関数は、ボリュームということですから、
ひょっとして、No1487中 ↓
数値が多くなったら,AのLEDをつけて消す,
数値が少なくなったら,BのLEDをつけて消す。
この内容を示しているのでしょうか?
追記 ↓ですね?(英訳したら増大という意味だったので、電圧が増えるときの関数だと思っていました。
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
ひょっとして、No1487中 ↓
数値が多くなったら,AのLEDをつけて消す,
数値が少なくなったら,BのLEDをつけて消す。
この内容を示しているのでしょうか?
追記 ↓ですね?(英訳したら増大という意味だったので、電圧が増えるときの関数だと思っていました。
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
Re: 続続ーPWM
まねて、ちょっと変えて、以下の通りやってみましたが
ダメでした。
if分の書き方を変えています。
16F1827です。
/*RB4で電圧読み取り*/
//RB7が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニターLED緑で点滅させる
//RA0は電圧DownのモニターLED黄で点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//RA4はINCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
// メイン関数
void main(void) {
OPTION_REGbits.nWPUEN = 0; //内部プルアップ有効
OSCCON = 0b0111001; //クロック周波数を16MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b10010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
//変数宣言
int i;
int hozon=1024;
int newhozon=1024;
while (1) {
adconv();//adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if(hozon!= adoconv()){
newhozon=adconv();
RA2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=!LATA1;
__delay_us(100);//調整の必要ありそう
LATA1=0;
else if((hozon-newhozon)<0){
RA3=0;//U/Dピンをダウンに設定
LATA0=!LATA0;
__delay_us(100);//調整の必要ありそう
LATA0=0;
}
else{
RA2 = 1; //CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
ダメでした。
if分の書き方を変えています。
16F1827です。
/*RB4で電圧読み取り*/
//RB7が汎用出力14番_SEC基板ポート2のSL-18の1番ピン(出力端子)を入力端子として受ける
//RA1が電圧UPのモニターLED緑で点滅させる
//RA0は電圧DownのモニターLED黄で点滅させる
//RA2はデジタル抵抗のCSピンへ
//RA3はデジタル抵抗のU/Dピンへ
//RA4はINCピンはプルアップで常時HIにする
//PIC16F1827 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
// クロック周波数指定
// (__delay_ms()関数が必要としているため)
#define _XTAL_FREQ 16000000
// プロトタイプ宣言
unsigned int adconv(void); //ADC読み込み関数
// メイン関数
void main(void) {
OPTION_REGbits.nWPUEN = 0; //内部プルアップ有効
OSCCON = 0b0111001; //クロック周波数を16MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00010000; // 可変抵抗の電圧読み込み用にRB4のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b10010000; //RB4 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
//変数宣言
int i;
int hozon=1024;
int newhozon=1024;
while (1) {
adconv();//adc 読み込み関数呼び出し
__delay_us(50); // アクィジション時間(50マイクロ秒)
if(hozon!= adoconv()){
newhozon=adconv();
RA2=0;//CSピンコマンド待ち
for(i=0;i<abs((hozon-newhozon)/100));i++){
if((hozon-newhozon)>0){
RA3=1;//U/Dピンをアップに設定
LATA1=!LATA1;
__delay_us(100);//調整の必要ありそう
LATA1=0;
else if((hozon-newhozon)<0){
RA3=0;//U/Dピンをダウンに設定
LATA0=!LATA0;
__delay_us(100);//調整の必要ありそう
LATA0=0;
}
else{
RA2 = 1; //CSピン_メモリー書き込み(ワイパー姿勢を保存します。)
}
}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
return ADRES;
}
Re: 続続ーPWM
TRさん,こんばんは。
いろいろやっておられますね。
亀レスですみません。
>setADCChannel(0);
ですけど,これ while ループの中で設定してますよね。
意図があるのか分かりませんが,
一度設定したら,OKかもしれませんね。
それから,
>for(i=0;i<abs((hozon-newhozon)/100));i++){
100で割る意味?
の100で÷意味ですが AD 変換で読み取った数値
で,抵抗を10段階で調整しては,ということで,
100でわりました。
AD変換の読み取りの数値は,0〜1024までの数値という
ことでやりましたが,この上の読み取りだと,
変更ですね。
それから,
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
}
かっこが抜けてましたね。
誤 increse{
正 increse(){
1827プログラムはちょっと,みてみますね。
PWMの基本周波数変更
100Hz→10kHz
のプログラムでもがいていました。
原因は,PWM発生機のようで,
DUTY比0にしても,パルスが出たりでなかったりです。
いろいろやっておられますね。
亀レスですみません。
>setADCChannel(0);
ですけど,これ while ループの中で設定してますよね。
意図があるのか分かりませんが,
一度設定したら,OKかもしれませんね。
それから,
>for(i=0;i<abs((hozon-newhozon)/100));i++){
100で割る意味?
の100で÷意味ですが AD 変換で読み取った数値
で,抵抗を10段階で調整しては,ということで,
100でわりました。
AD変換の読み取りの数値は,0〜1024までの数値という
ことでやりましたが,この上の読み取りだと,
変更ですね。
それから,
increse{
RB1=0;
__delay_us(10);//調整の必要ありそう
RB1=1;
}
かっこが抜けてましたね。
誤 increse{
正 increse(){
1827プログラムはちょっと,みてみますね。
PWMの基本周波数変更
100Hz→10kHz
のプログラムでもがいていました。
原因は,PWM発生機のようで,
DUTY比0にしても,パルスが出たりでなかったりです。
Re: 続続ーPWM
>原因は,PWM発生機のようで,
DUTY比0にしても,パルスが出たりでなかったりです。
不良品でしたね。
原因が分かってよかったですね。
ADチャンネルは、電圧読み取り端子の設定だと思うので、
プロトタイプ宣言はせずに、簡単にします。
方法
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
プログラムのエラーは、
多分、AD変換後の比較方法にあるような気がします。
その部分が、赤くなっています。
何度かえてみてもうまくいきません。
お知恵拝借します。
どうぞ、宜しくお願いします。
DUTY比0にしても,パルスが出たりでなかったりです。
不良品でしたね。
原因が分かってよかったですね。
ADチャンネルは、電圧読み取り端子の設定だと思うので、
プロトタイプ宣言はせずに、簡単にします。
方法
// ADコンバータ設定
ADCON0 = 0b00100001; // アナログ変換情報(RB4から読込む)
ADCON1 = 0b11010000; // 読取値は右寄せ、A/D変換クロックはFOSC/16、VDDをリファレンスとする
プログラムのエラーは、
多分、AD変換後の比較方法にあるような気がします。
その部分が、赤くなっています。
何度かえてみてもうまくいきません。
お知恵拝借します。
どうぞ、宜しくお願いします。
- JoyfulNote v6.02 -
++ Edited by Hamel ++