トピック関連記事
48時間以内の記事は で表示されます
疑似手パ,中間報告
手パの経過報告です。
幾つかの問題に直面しました。
部材(スライドスイッチ)が25日発送予定なので、どちらにしてもまだなのですけど、
プログラムとCADの部分はおおよそ作って、テストしています。
@一番大きな問題ですけど、「CTRL」+「ALT」+「X」が通用しません。
試してみると、「CTRL」+「X」や「ALT」+「X」なら問題無さそうです。
(STM32F103ボード、PRO MICRO共通)
勿論、本物のキーボードからは「CTRL」+「ALT」+「X」で通用します。
今の所、解決策は3つです。
1.根本的に、プログラム(ライブラリ)を見直して、「CTRL」+「ALT」+が通用するものを作る
2.ホットキーの割り当てを変える。
3.今まで行っていたJoyToKeyというソフトを使うなら通用するでしょうから、
ジョイパッドとして作って、JoyToKeyを通して作業するなら問題はすり抜けそうです。
今の所、2番の割り当て変更になりそうです。ただ、元々どこに当てられているのかがはっきりしないんですよね。
一覧とかがあれば、「それ以外」も決めれるのですけど。
ASTM32F103ボードにはBOOTジャンパが付いています。これで、起動を切り替えるのですけど、
これが邪魔で予定ケースには入らないことが判明しました。ピンヘッダを削ってはんだ付けしちゃうか?ケースに
穴をあけるか、それともピンヘッダの無いPRO MICROにするか?まぁ、ケースを変える、というのもありましたね。
添付画像のように、PRO MICROは平らです。リセットボタンやISPピンも出てないのが今回は好結果になります。
(勿論あった方が使いやすいですけど、この平べったさをみると意図的にしているようですね)
これはちょっとPRO MICROに気持ちが傾いています。ジャンパを取ってもちょっと膨れる位なんですよね。
B以前MABOさんから、「フォルムさんの疑似手パは使いにくかった」というようなことを聞いたような気がするのですけど、
それと同じような要因なのかと思います。
CONTモードの時はボタンが直ぐに切り替わりません。0.5秒位は離さないと次の命令(ボタンを押す)を聞いてくれません。
最初にこれに遭遇したので戸惑いました。
(これはキーボードでも確認できます。→キーを押してX+方向にうごかしていて、直ぐに←キーに切り替えるとX-には動かずに停止します。
また、同じキーの2度打ちでも停止します)
ただし、stepモードの場合は
> for (i = 0; i < 100; i++) {
> BootKeyboard.press(KEY_PAGE_UP);
> delay(3);
> BootKeyboard.release(KEY_PAGE_UP);
> delay(3);
> }
のコードで動くことを確認しました。(0.01mm×100回押す=1mm動作)
エンコーダ自体は1周30パルスなので、早く回しても1秒間に3回転=90パルス/秒です。
これで動いたと言う事は160パルス/秒でも問題ないことを意味しているので、STEPモードにすれば
ちゃんと動きそうです。
幾つかの問題に直面しました。
部材(スライドスイッチ)が25日発送予定なので、どちらにしてもまだなのですけど、
プログラムとCADの部分はおおよそ作って、テストしています。
@一番大きな問題ですけど、「CTRL」+「ALT」+「X」が通用しません。
試してみると、「CTRL」+「X」や「ALT」+「X」なら問題無さそうです。
(STM32F103ボード、PRO MICRO共通)
勿論、本物のキーボードからは「CTRL」+「ALT」+「X」で通用します。
今の所、解決策は3つです。
1.根本的に、プログラム(ライブラリ)を見直して、「CTRL」+「ALT」+が通用するものを作る
2.ホットキーの割り当てを変える。
3.今まで行っていたJoyToKeyというソフトを使うなら通用するでしょうから、
ジョイパッドとして作って、JoyToKeyを通して作業するなら問題はすり抜けそうです。
今の所、2番の割り当て変更になりそうです。ただ、元々どこに当てられているのかがはっきりしないんですよね。
一覧とかがあれば、「それ以外」も決めれるのですけど。
ASTM32F103ボードにはBOOTジャンパが付いています。これで、起動を切り替えるのですけど、
これが邪魔で予定ケースには入らないことが判明しました。ピンヘッダを削ってはんだ付けしちゃうか?ケースに
穴をあけるか、それともピンヘッダの無いPRO MICROにするか?まぁ、ケースを変える、というのもありましたね。
添付画像のように、PRO MICROは平らです。リセットボタンやISPピンも出てないのが今回は好結果になります。
(勿論あった方が使いやすいですけど、この平べったさをみると意図的にしているようですね)
これはちょっとPRO MICROに気持ちが傾いています。ジャンパを取ってもちょっと膨れる位なんですよね。
B以前MABOさんから、「フォルムさんの疑似手パは使いにくかった」というようなことを聞いたような気がするのですけど、
それと同じような要因なのかと思います。
CONTモードの時はボタンが直ぐに切り替わりません。0.5秒位は離さないと次の命令(ボタンを押す)を聞いてくれません。
最初にこれに遭遇したので戸惑いました。
(これはキーボードでも確認できます。→キーを押してX+方向にうごかしていて、直ぐに←キーに切り替えるとX-には動かずに停止します。
また、同じキーの2度打ちでも停止します)
ただし、stepモードの場合は
> for (i = 0; i < 100; i++) {
> BootKeyboard.press(KEY_PAGE_UP);
> delay(3);
> BootKeyboard.release(KEY_PAGE_UP);
> delay(3);
> }
のコードで動くことを確認しました。(0.01mm×100回押す=1mm動作)
エンコーダ自体は1周30パルスなので、早く回しても1秒間に3回転=90パルス/秒です。
これで動いたと言う事は160パルス/秒でも問題ないことを意味しているので、STEPモードにすれば
ちゃんと動きそうです。
猛牛ロック 2018/12/23(Sun) 10:23 No.1363
Re: 疑似手パ,中間報告
猛牛ロックさん,TRさん,こんばんは。
猛牛ロックさん,着々とすすでますね。
ちょっと疑問点なんですが,
USB接続だと思うのですが,
USBまわりのライブラりーでもあるのでしょうか。
それと,
BootKeyboard.press(KEY_PAGE_UP)
のKEY_PAGE_UPは,猛牛ロックさんが別途作った,Define等で
の処理でしょうか。
それとも,一括で,ヘッダーフィアイルかんなんかにあるのでしょうか。
猛牛ロックさん,着々とすすでますね。
ちょっと疑問点なんですが,
USB接続だと思うのですが,
USBまわりのライブラりーでもあるのでしょうか。
それと,
BootKeyboard.press(KEY_PAGE_UP)
のKEY_PAGE_UPは,猛牛ロックさんが別途作った,Define等で
の処理でしょうか。
それとも,一括で,ヘッダーフィアイルかんなんかにあるのでしょうか。
mabo 2018/12/23(Sun) 20:48 No.1364
Re: 疑似手パ,中間報告
HIDデバイス絡みのライブラリです。
HIDデバイスなら、標準ドライバで動くのでドライバを作る必要もありません。
マウス、キーボード、ジョイパッドあたりのデバイスです。
数日前に参考プログラムを乗せたと思うのですけど。(No.1347です)
STM32F103ボードの方はコンポジットライブラリ(それらの複合)になっていて、
モードが幾つかあるので面倒です。でも基本は一緒で、
#include <USBComposite.h>
USBHID HID;
HIDKeyboard BootKeyboard(HID, 0);
void setup() {
HID.begin(HID_BOOT_KEYBOARD);
BootKeyboard.begin();
まで記述すれば、既に始める準備が出来ています。
後は
BootKeyboard.press('M');
BootKeyboard.release('M');
BootKeyboard.write('M');//押して離す複合
BootKeyboard.releaseAll();
の類の命令を状況に応じて書くだけです。
※「BootKeyboard」は自由に付けていいはずです。。
なので3行目は
HIDKeyboard TEPA(HID, 0);
とすれば、6行目は
TEPA.begin();
として、
TEPA.press('k');
のように使います。
PRO MICROは単独のHIDキーボードライブラリのなので、もっと簡単に
#include "Keyboard.h"
void setup() {
Keyboard.begin();
}
の2行を付けれるだけで準備OKです。
KEY_PAGE_UP
等は既に定義されています。
まともなマニュアルはありませんから、ライブラリ内を検索して、実際にはUSBHID.hというファイルに定義されていました。
(Arduinoの方はリファレンスサイトに載っています。勿論PICにも同様のライブラリはあると思います。
ただし、PRO MICRO(実際はLEONARDOのライブラリ)とSTM32ボードやPIC、その他のライブラリでそれぞれ違いはあります。
どれも、その仕様に沿って書くことになります。)
HIDデバイスなら、標準ドライバで動くのでドライバを作る必要もありません。
マウス、キーボード、ジョイパッドあたりのデバイスです。
数日前に参考プログラムを乗せたと思うのですけど。(No.1347です)
STM32F103ボードの方はコンポジットライブラリ(それらの複合)になっていて、
モードが幾つかあるので面倒です。でも基本は一緒で、
#include <USBComposite.h>
USBHID HID;
HIDKeyboard BootKeyboard(HID, 0);
void setup() {
HID.begin(HID_BOOT_KEYBOARD);
BootKeyboard.begin();
まで記述すれば、既に始める準備が出来ています。
後は
BootKeyboard.press('M');
BootKeyboard.release('M');
BootKeyboard.write('M');//押して離す複合
BootKeyboard.releaseAll();
の類の命令を状況に応じて書くだけです。
※「BootKeyboard」は自由に付けていいはずです。。
なので3行目は
HIDKeyboard TEPA(HID, 0);
とすれば、6行目は
TEPA.begin();
として、
TEPA.press('k');
のように使います。
PRO MICROは単独のHIDキーボードライブラリのなので、もっと簡単に
#include "Keyboard.h"
void setup() {
Keyboard.begin();
}
の2行を付けれるだけで準備OKです。
KEY_PAGE_UP
等は既に定義されています。
まともなマニュアルはありませんから、ライブラリ内を検索して、実際にはUSBHID.hというファイルに定義されていました。
(Arduinoの方はリファレンスサイトに載っています。勿論PICにも同様のライブラリはあると思います。
ただし、PRO MICRO(実際はLEONARDOのライブラリ)とSTM32ボードやPIC、その他のライブラリでそれぞれ違いはあります。
どれも、その仕様に沿って書くことになります。)
猛牛ロック 2018/12/23(Sun) 23:09 No.1365
Re: 疑似手パ,中間報告
Re: 疑似手パ,中間報告
Re: 疑似手パ,中間報告
使用マイコンの方はまだどちらにするか悩んでいます。
ホットキーについては、はっきりとしたことは判りません。
例えば、Ctrl+ALT+1(Qキーの上にある方)だとマイコンもキーボードも同一です。
しかし、特定のものはやはり違った値になります。
でも、まぁ、マイコンはどちらにしろ、この問題はあるようですし、対処できない訳でもないので
この部分で悩んでいる訳でもないのですけど。
・あまりADCは使いたくない→STM32ボードが良いかなぁ
・ピンヘッダが邪魔→PRO MICROの方がすっきりするかなぁ
今となっては使うか判らないSTM32ボード用の最初のスケッチです。
実際試した訳では無いので、多少変えないと動かないと思います。
大部分は、「押したボタンに対応するコードを送る」というだけです。
こっちはブートキーボードじゃなくて、単なるキーボードになっていますね。
(何が違うのかは把握していません。今回の件ではどちらのモードでも同じかも)
#include <USBComposite.h>
const uint32_t used_pin=0b11111111110110000011111111111;
uint16_t pin_old[29];
uint8_t pin_state[29];
volatile uint8_t axis,feed,step_unit;
USBHID HID;
HIDKeyboard TEPA(HID);
void read_mode(void) {
for(byte i=0; i<=2; i++) {
if(digitalRead(i)==0)axis=i;
}
for(byte i=19; i<=22; i++) {
if(digitalRead(i)==0)step_unit=i;
}
for(byte i=23; i<=25; i++) {
if(digitalRead(i)==0)feed=i;
}
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('.'); //基本的に、STEPがデフォルト
if(step_unit==22)TEPA.write('K');
else if(step_unit==21)TEPA.write('L');
else if(step_unit==20)TEPA.write(';');
else if(step_unit==19)TEPA.write(':');
if(feed==25)TEPA.write('F');
else if(feed==24)TEPA.write('G');
else if(feed==23)TEPA.write('H');
TEPA.releaseAll();
}
void setup() {
HID.begin(HID_KEYBOARD);
TEPA.begin();
for(byte i=0; i<=28; i++) {
if((used_pin>>i)&1) {
pinMode(i,INPUT_PULLUP);
}
}
delay(1000);
read_mode();
}
void loop() {
byte enc;
for(byte i=0; i<=28; i++) { //16bit履歴を保存
if((used_pin>>i)&1) {
pin_old[i]<<=1;
if(digitalRead(i)==0) {//SW-ON
pin_old[i]++;
if(pin_old[i]=0xFFFF) {
if(i<=2 && i!=axis) {
axis=i;
} else if(i>=19 && i<=22 && i!=step_unit) {
step_unit=i;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==19)TEPA.press(':');
else if(i==20)TEPA.press(';');
else if(i==21)TEPA.press('L');
else if(i==22)TEPA.press('K');
TEPA.releaseAll();
} else if(i>=23 && i<=25 && i!=feed) {
feed=i;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==23)TEPA.press('H');
else if(i==24)TEPA.press('G');
else if(i==25)TEPA.press('F');
TEPA.releaseAll();
} else if(i==3 && pin_state[3]==0) { //1/2
pin_state[3]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('A');
else if(axis==1)TEPA.press('S');
else if(axis==2)TEPA.press('D');
TEPA.releaseAll();
} else if(i==4 && pin_state[i]==0) { //z1.02
pin_state[4]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('/');
TEPA.releaseAll();
} else if(i==5 && pin_state[i]==0) { //DRO 0
pin_state[5]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('B');
else if(axis==1)TEPA.press('N');
else if(axis==2)TEPA.press('M');
TEPA.releaseAll();
} else if(i<=8 && pin_state[i]==0) { //g56,55,54
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==8)TEPA.press('4');
else if(i==7)TEPA.press('5');
else if(i==6)TEPA.press('6');
TEPA.releaseAll();
} else if(i==26 && pin_state[i]==0) { //stop
pin_state[i]=1;
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('S');
TEPA.releaseAll();
} else if(i==27 && pin_state[i]==0) {
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('W');
else if(axis==1)TEPA.press('E');
else if(axis==2)TEPA.press('R');
TEPA.releaseAll();
} else if(i==28 && pin_state[i]==0) { //G0z1
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('Z');
TEPA.releaseAll();;
} else if(i==9 && pin_state[i]==0) { //+ ※releaseはしない
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.write(',');//CONT指定
if(axis==0)TEPA.press(KEY_RIGHT_ARROW);
else if(axis==1)TEPA.press(KEY_UP_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_UP);
} else if(i==10 && pin_state[i]==0) { //- ※releaseはしない
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.write(',');//CONT指定
if(axis==0)TEPA.press(KEY_LEFT_ARROW);
else if(axis==1)TEPA.press(KEY_DOWN_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_DOWN);
}
}
} else { //SW-OFF
if(pin_old[i]==0) {
if((i==9 || i==10)&& pin_state[i]==1) {
pin_state[i]=0;
TEPA.releaseAll();
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('.');//STEP指定
TEPA.releaseAll();
} else if(pin_state[i]==1)pin_state[i]=0;
}
}
enc=((pin_old[16]&0b11)<<2)|(pin_old[17]&0b11);//step-cont切替も
if(enc==1) {
if(axis==0)TEPA.write(KEY_RIGHT_ARROW);
else if(axis==1)TEPA.write(KEY_UP_ARROW);
else if(axis==2)TEPA.write(KEY_PAGE_UP);
} else if(enc==2) {
if(axis==0)TEPA.press(KEY_LEFT_ARROW);
else if(axis==1)TEPA.press(KEY_DOWN_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_DOWN);
}
}
}
delay(1);
}
ホットキーについては、はっきりとしたことは判りません。
例えば、Ctrl+ALT+1(Qキーの上にある方)だとマイコンもキーボードも同一です。
しかし、特定のものはやはり違った値になります。
でも、まぁ、マイコンはどちらにしろ、この問題はあるようですし、対処できない訳でもないので
この部分で悩んでいる訳でもないのですけど。
・あまりADCは使いたくない→STM32ボードが良いかなぁ
・ピンヘッダが邪魔→PRO MICROの方がすっきりするかなぁ
今となっては使うか判らないSTM32ボード用の最初のスケッチです。
実際試した訳では無いので、多少変えないと動かないと思います。
大部分は、「押したボタンに対応するコードを送る」というだけです。
こっちはブートキーボードじゃなくて、単なるキーボードになっていますね。
(何が違うのかは把握していません。今回の件ではどちらのモードでも同じかも)
#include <USBComposite.h>
const uint32_t used_pin=0b11111111110110000011111111111;
uint16_t pin_old[29];
uint8_t pin_state[29];
volatile uint8_t axis,feed,step_unit;
USBHID HID;
HIDKeyboard TEPA(HID);
void read_mode(void) {
for(byte i=0; i<=2; i++) {
if(digitalRead(i)==0)axis=i;
}
for(byte i=19; i<=22; i++) {
if(digitalRead(i)==0)step_unit=i;
}
for(byte i=23; i<=25; i++) {
if(digitalRead(i)==0)feed=i;
}
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('.'); //基本的に、STEPがデフォルト
if(step_unit==22)TEPA.write('K');
else if(step_unit==21)TEPA.write('L');
else if(step_unit==20)TEPA.write(';');
else if(step_unit==19)TEPA.write(':');
if(feed==25)TEPA.write('F');
else if(feed==24)TEPA.write('G');
else if(feed==23)TEPA.write('H');
TEPA.releaseAll();
}
void setup() {
HID.begin(HID_KEYBOARD);
TEPA.begin();
for(byte i=0; i<=28; i++) {
if((used_pin>>i)&1) {
pinMode(i,INPUT_PULLUP);
}
}
delay(1000);
read_mode();
}
void loop() {
byte enc;
for(byte i=0; i<=28; i++) { //16bit履歴を保存
if((used_pin>>i)&1) {
pin_old[i]<<=1;
if(digitalRead(i)==0) {//SW-ON
pin_old[i]++;
if(pin_old[i]=0xFFFF) {
if(i<=2 && i!=axis) {
axis=i;
} else if(i>=19 && i<=22 && i!=step_unit) {
step_unit=i;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==19)TEPA.press(':');
else if(i==20)TEPA.press(';');
else if(i==21)TEPA.press('L');
else if(i==22)TEPA.press('K');
TEPA.releaseAll();
} else if(i>=23 && i<=25 && i!=feed) {
feed=i;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==23)TEPA.press('H');
else if(i==24)TEPA.press('G');
else if(i==25)TEPA.press('F');
TEPA.releaseAll();
} else if(i==3 && pin_state[3]==0) { //1/2
pin_state[3]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('A');
else if(axis==1)TEPA.press('S');
else if(axis==2)TEPA.press('D');
TEPA.releaseAll();
} else if(i==4 && pin_state[i]==0) { //z1.02
pin_state[4]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('/');
TEPA.releaseAll();
} else if(i==5 && pin_state[i]==0) { //DRO 0
pin_state[5]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('B');
else if(axis==1)TEPA.press('N');
else if(axis==2)TEPA.press('M');
TEPA.releaseAll();
} else if(i<=8 && pin_state[i]==0) { //g56,55,54
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(i==8)TEPA.press('4');
else if(i==7)TEPA.press('5');
else if(i==6)TEPA.press('6');
TEPA.releaseAll();
} else if(i==26 && pin_state[i]==0) { //stop
pin_state[i]=1;
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('S');
TEPA.releaseAll();
} else if(i==27 && pin_state[i]==0) {
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
if(axis==0)TEPA.press('W');
else if(axis==1)TEPA.press('E');
else if(axis==2)TEPA.press('R');
TEPA.releaseAll();
} else if(i==28 && pin_state[i]==0) { //G0z1
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('Z');
TEPA.releaseAll();;
} else if(i==9 && pin_state[i]==0) { //+ ※releaseはしない
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.write(',');//CONT指定
if(axis==0)TEPA.press(KEY_RIGHT_ARROW);
else if(axis==1)TEPA.press(KEY_UP_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_UP);
} else if(i==10 && pin_state[i]==0) { //- ※releaseはしない
pin_state[i]=1;
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.write(',');//CONT指定
if(axis==0)TEPA.press(KEY_LEFT_ARROW);
else if(axis==1)TEPA.press(KEY_DOWN_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_DOWN);
}
}
} else { //SW-OFF
if(pin_old[i]==0) {
if((i==9 || i==10)&& pin_state[i]==1) {
pin_state[i]=0;
TEPA.releaseAll();
TEPA.press(KEY_RIGHT_CTRL);
TEPA.press(KEY_RIGHT_ALT);
TEPA.press('.');//STEP指定
TEPA.releaseAll();
} else if(pin_state[i]==1)pin_state[i]=0;
}
}
enc=((pin_old[16]&0b11)<<2)|(pin_old[17]&0b11);//step-cont切替も
if(enc==1) {
if(axis==0)TEPA.write(KEY_RIGHT_ARROW);
else if(axis==1)TEPA.write(KEY_UP_ARROW);
else if(axis==2)TEPA.write(KEY_PAGE_UP);
} else if(enc==2) {
if(axis==0)TEPA.press(KEY_LEFT_ARROW);
else if(axis==1)TEPA.press(KEY_DOWN_ARROW);
else if(axis==2)TEPA.press(KEY_PAGE_DOWN);
}
}
}
delay(1);
}
猛牛ロック 2018/12/24(Mon) 19:00 No.1368
Re: 疑似手パ,中間報告
猛牛ロックさん,TRさん,こんばんは。
猛牛ロックさん,疑問点への回答ありがとうございます。
arduino,ライブラリー等,充実してるんですね。
機種にもよるのでしょうけど,本当,親切ですね。
16系のPICだと,新しいものでないと,USBのインターフェース等,搭載してないようですね。
私がもっている,16ファミリーでの解説書でも,USBのインターフェ-スについては,載ってないです。
STM32F103のUSBのライブラリ-ちょっとみてみました。
https://github.com/arpruss/USBComposite_stm32f1
PICのこともよく分からないのですが,arduinoは,なんか充実しているような感じです。
PICだと16系では,16F1455がUSBのインターフェース搭載なのですね。
秋月での販売が2016年あたりですので,新しいですよね。
このあたりは。arduino の方が進んでるんでしょうかね。
TRさん,PWMのコントローラーの不具合,原因分かってよかったですね。
ICは,もしかして,中華製だったりして・・・・・・。
ICの交換より,全体の買い換えの方が安くつくんでしょうかね。
猛牛ロックさん,疑問点への回答ありがとうございます。
arduino,ライブラリー等,充実してるんですね。
機種にもよるのでしょうけど,本当,親切ですね。
16系のPICだと,新しいものでないと,USBのインターフェース等,搭載してないようですね。
私がもっている,16ファミリーでの解説書でも,USBのインターフェ-スについては,載ってないです。
STM32F103のUSBのライブラリ-ちょっとみてみました。
https://github.com/arpruss/USBComposite_stm32f1
PICのこともよく分からないのですが,arduinoは,なんか充実しているような感じです。
PICだと16系では,16F1455がUSBのインターフェース搭載なのですね。
秋月での販売が2016年あたりですので,新しいですよね。
このあたりは。arduino の方が進んでるんでしょうかね。
TRさん,PWMのコントローラーの不具合,原因分かってよかったですね。
ICは,もしかして,中華製だったりして・・・・・・。
ICの交換より,全体の買い換えの方が安くつくんでしょうかね。
mabo 2018/12/25(Tue) 21:04 No.1370
Re: 疑似手パ,中間報告
Re: 疑似手パ,中間報告
> MABOさん
基本的に、上位のマイコンほど複雑ですけど、逆に複雑な部分は捨て去って?、簡単になります。
PCは内部は複雑だけれども、それを知らなくてもすぐにインターネットやEXCELが出来るのと同じです。
まぁ、複雑な部分は他人に任せているのですけど。
基本的に、Arduinoもmbedなども同じ(WINDOWSとMACのようなもの)で、それに対応させれば、同じような操作で
GPIO等は操れます。(Arduinoに対応したデバイスはArduino流に書いて、mbedならmbed流に書く)
Arduino(UNO)なら、レジスタ操作からライブラリを使った、様々なデバイスも容易に纏められます。
つまり、入門から応用まで対応出来ます。
PICでそう言った事が出来るかは、良く判りません。(勿論、マイコン性能ではなく、開発環境の問題です)
USBもPIC16Fからありますし、品ぞろえ的にはPICは問題ないです。
だけど、設定が面倒なんですよね。だから、http://bit-trade-one.co.jp/product/assemblydisk/revive-usb/
のような物も発売されています。
でも、多少いじるなら、このコードを改変するよりも、https://garretlab.web.fc2.com/arduino_reference/language/functions/usb/index.html
を見て、Arduinoで組んだ方が楽で面白いかと思います。
> TRさん
プログラム自体は全然難しいものではありませんよ。
ボタンを押されたら1回点滅させる、というLチカと同じ類のものです。
それが、1回(そのボタンに対応する)キーコードを送る、となっているだけです。
で、その回路ですけど、
・FETは4V(或いは2.5V)駆動品を選ぶ
・プルダウン抵抗は高すぎです。数十kΩが良いです。
・3.5kΩの部分はプルダウン抵抗の1/10程度が良いかな?
・バリスタよりもダイオードが良いです。
※バリスタ27Vなら実際のバリスタ電圧?が30Vとして、42Vになった時にDC12V側に還流されます。
つまり、42Vのサージが残ります。
ダイオードなら12.6Vで還流されるので、ほぼサージが消えます。
基本的に、上位のマイコンほど複雑ですけど、逆に複雑な部分は捨て去って?、簡単になります。
PCは内部は複雑だけれども、それを知らなくてもすぐにインターネットやEXCELが出来るのと同じです。
まぁ、複雑な部分は他人に任せているのですけど。
基本的に、Arduinoもmbedなども同じ(WINDOWSとMACのようなもの)で、それに対応させれば、同じような操作で
GPIO等は操れます。(Arduinoに対応したデバイスはArduino流に書いて、mbedならmbed流に書く)
Arduino(UNO)なら、レジスタ操作からライブラリを使った、様々なデバイスも容易に纏められます。
つまり、入門から応用まで対応出来ます。
PICでそう言った事が出来るかは、良く判りません。(勿論、マイコン性能ではなく、開発環境の問題です)
USBもPIC16Fからありますし、品ぞろえ的にはPICは問題ないです。
だけど、設定が面倒なんですよね。だから、http://bit-trade-one.co.jp/product/assemblydisk/revive-usb/
のような物も発売されています。
でも、多少いじるなら、このコードを改変するよりも、https://garretlab.web.fc2.com/arduino_reference/language/functions/usb/index.html
を見て、Arduinoで組んだ方が楽で面白いかと思います。
> TRさん
プログラム自体は全然難しいものではありませんよ。
ボタンを押されたら1回点滅させる、というLチカと同じ類のものです。
それが、1回(そのボタンに対応する)キーコードを送る、となっているだけです。
で、その回路ですけど、
・FETは4V(或いは2.5V)駆動品を選ぶ
・プルダウン抵抗は高すぎです。数十kΩが良いです。
・3.5kΩの部分はプルダウン抵抗の1/10程度が良いかな?
・バリスタよりもダイオードが良いです。
※バリスタ27Vなら実際のバリスタ電圧?が30Vとして、42Vになった時にDC12V側に還流されます。
つまり、42Vのサージが残ります。
ダイオードなら12.6Vで還流されるので、ほぼサージが消えます。
猛牛ロック 2018/12/26(Wed) 12:37 No.1372
Re: 疑似手パ,中間報告
猛牛ロックさんへ、
先ほど、バラックでテスト完了しました。
中華ポンプは、えらくいい加減です。
動作する電圧の範囲です。
表示はDC12Vですが、DC24でも行けそうです。
バリスタはどうって選ぶのか分かりませんでした。
以下のページを参考にして、出しました。
VE≦VA(1−α) …A
VE:回路電圧
VA:最大許容回路電圧
α:設計マージン(α=0.2)
http://www.koaglobal.com/product/basic/varistor
本当は違うのですか、よかったら、
詳しく教えてください。
MOSFETの1MΩは、自信があります。
続トランジスタ回路の設計から出しましたし、実験の結果、やはり1MΩじゃないと、
GND側に引っ張り切れなくて、ドレインから電流が流れてしまいました。
FET方向への3.9kΩは、実験の結果、一番安定していました。
ただ、参考文献でもハッキリとしませんでした。
バリスタは、高速ダイオードに変えます。
それから、教えていただいたPWMとADのプログラムは、理解できたので、
大活躍していますよ。
バラックでのテストは、安定電源でやったので、ポンプ無理なく滑らかに回っています。
ボリュームをいじっていると気分がいいです。
ただ、ポンプがいまいち、ボリュームを目いっぱいに絞っていないのに停止します。
これはプログラムじゃなくポンプです。
なにせ、DC18Vの電源だとパワフルに回ってくれますから、きっと、最適の電圧は12Vじゃなくもっと上だと思います。
言語は、MPLABの言語じゃないのですか?
写真は、バラックでのテスト風景です。
先ほど、バラックでテスト完了しました。
中華ポンプは、えらくいい加減です。
動作する電圧の範囲です。
表示はDC12Vですが、DC24でも行けそうです。
バリスタはどうって選ぶのか分かりませんでした。
以下のページを参考にして、出しました。
VE≦VA(1−α) …A
VE:回路電圧
VA:最大許容回路電圧
α:設計マージン(α=0.2)
http://www.koaglobal.com/product/basic/varistor
本当は違うのですか、よかったら、
詳しく教えてください。
MOSFETの1MΩは、自信があります。
続トランジスタ回路の設計から出しましたし、実験の結果、やはり1MΩじゃないと、
GND側に引っ張り切れなくて、ドレインから電流が流れてしまいました。
FET方向への3.9kΩは、実験の結果、一番安定していました。
ただ、参考文献でもハッキリとしませんでした。
バリスタは、高速ダイオードに変えます。
それから、教えていただいたPWMとADのプログラムは、理解できたので、
大活躍していますよ。
バラックでのテストは、安定電源でやったので、ポンプ無理なく滑らかに回っています。
ボリュームをいじっていると気分がいいです。
ただ、ポンプがいまいち、ボリュームを目いっぱいに絞っていないのに停止します。
これはプログラムじゃなくポンプです。
なにせ、DC18Vの電源だとパワフルに回ってくれますから、きっと、最適の電圧は12Vじゃなくもっと上だと思います。
言語は、MPLABの言語じゃないのですか?
写真は、バラックでのテスト風景です。
Re: 疑似手パ,中間報告
皆さんこんばんは。
教えて欲しい事があります。
SEC基板のポート2 SL13の1 からの出力信号(これが、「-電圧」なんです、、、。)。
今まで、逆に繋いでいました。
話を戻します。
PWMをSL13の1からの信号をRB7に繋ぎ、RB7により全体を制御したいと思います。
そこで、プログラムの真ん中あたり、@のところに、break文を付けました。
これで、宜しいでしょうか?
動作
RB7のLoで、すべて停止、
Hiで、
・全体の動作モニター用のLED
・PWM信号をRB0端子で、DCモーターポンプを回転数制御
・RB3で回転数を電圧読み取り
/*PWM機能によりRB3可変抵抗で制御*/
//RB7がSEC基板ポート2のSL-13の1番ピン(出力端子)を入力端子として受けるその表示をLEDでRA1から発光させる
//RB0を出力端子LEDPIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
// 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 1000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を1MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00001000; // 可変抵抗の電圧読み込み用にRB3のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00001000; //RB3 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100101; // アナログ変換情報設定(AN9 RB3から読込む)
ADCON1 = 0b10010000; // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスとする
__delay_us(5); // アナログ変換情報が設定されるまでとりあえず待つ
//変数宣言
unsigned int num;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
@ if(RB7==0){break;}
LATA1=RB7;//SEC基板ポート2のSL-13の1番ピン
num = adconv(); // RB3 9番ピン(AN9)から半固定抵抗の値を読み込む
CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
CCP1CONbits.DC1B = num & 0b11;
__delay_ms(10);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
APFCON0bits.CCP1SEL = 1; // RB0端子を出力端子に設定
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 255; //PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
教えて欲しい事があります。
SEC基板のポート2 SL13の1 からの出力信号(これが、「-電圧」なんです、、、。)。
今まで、逆に繋いでいました。
話を戻します。
PWMをSL13の1からの信号をRB7に繋ぎ、RB7により全体を制御したいと思います。
そこで、プログラムの真ん中あたり、@のところに、break文を付けました。
これで、宜しいでしょうか?
動作
RB7のLoで、すべて停止、
Hiで、
・全体の動作モニター用のLED
・PWM信号をRB0端子で、DCモーターポンプを回転数制御
・RB3で回転数を電圧読み取り
/*PWM機能によりRB3可変抵抗で制御*/
//RB7がSEC基板ポート2のSL-13の1番ピン(出力端子)を入力端子として受けるその表示をLEDでRA1から発光させる
//RB0を出力端子LEDPIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
// 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 1000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を1MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00001000; // 可変抵抗の電圧読み込み用にRB3のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00001000; //RB3 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100101; // アナログ変換情報設定(AN9 RB3から読込む)
ADCON1 = 0b10010000; // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスとする
__delay_us(5); // アナログ変換情報が設定されるまでとりあえず待つ
//変数宣言
unsigned int num;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
@ if(RB7==0){break;}
LATA1=RB7;//SEC基板ポート2のSL-13の1番ピン
num = adconv(); // RB3 9番ピン(AN9)から半固定抵抗の値を読み込む
CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
CCP1CONbits.DC1B = num & 0b11;
__delay_ms(10);
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
APFCON0bits.CCP1SEL = 1; // RB0端子を出力端子に設定
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 255; //PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
Re: 疑似手パ,中間報告
DCモータは電圧によって力(回転数)が変わります。
なので、電圧を上げれば上げるほど回ります。
ただし、壊れる危険性も上がります。
電圧を2倍にすれば電流も2倍流れ、消費電力は4倍になります。当然発熱も4倍ですから気を付けてください。
> GND側に引っ張り切れなくて
誤解があるようですけど、1MΩよりも10kΩの方が引っ張る力は100倍あります。
けれども、あまりFETは使っていないので、どの位が適切かは自信がありません。
バリスタは交流の方が良く使われます。
交流の場合は素子の両側が入れ替わりますから、両方対処する必要があります。
例えばAC12Vなら最大17V程度ですよね?その場合は実効20Vのバリスタを入れれば最大値の3Vオーバーの値までにとどめられます。
でも、今回のようにDC12Vの場合は、20Vだと逆電流の場合は20+12V=32V以上の時にVCC(12V)側に流れる事になります。
で、ダイオードなら0.6V程度で流れだすのでこちらの方をお薦めします。
プログラムの方ですけど、はっきりとは言えませんけど多分、再起動を繰り返すのだと思います。
で、そこまでのプログラムではPWMはLOW状態なので、大体、LOW出力あるいはアナログ入力になると思います。
私自身はプログラムが終わるコードを書いたことが無いので、当然、試したこともありません。
なので、電圧を上げれば上げるほど回ります。
ただし、壊れる危険性も上がります。
電圧を2倍にすれば電流も2倍流れ、消費電力は4倍になります。当然発熱も4倍ですから気を付けてください。
> GND側に引っ張り切れなくて
誤解があるようですけど、1MΩよりも10kΩの方が引っ張る力は100倍あります。
けれども、あまりFETは使っていないので、どの位が適切かは自信がありません。
バリスタは交流の方が良く使われます。
交流の場合は素子の両側が入れ替わりますから、両方対処する必要があります。
例えばAC12Vなら最大17V程度ですよね?その場合は実効20Vのバリスタを入れれば最大値の3Vオーバーの値までにとどめられます。
でも、今回のようにDC12Vの場合は、20Vだと逆電流の場合は20+12V=32V以上の時にVCC(12V)側に流れる事になります。
で、ダイオードなら0.6V程度で流れだすのでこちらの方をお薦めします。
プログラムの方ですけど、はっきりとは言えませんけど多分、再起動を繰り返すのだと思います。
で、そこまでのプログラムではPWMはLOW状態なので、大体、LOW出力あるいはアナログ入力になると思います。
私自身はプログラムが終わるコードを書いたことが無いので、当然、試したこともありません。
猛牛ロック 2018/12/26(Wed) 22:36 No.1375
Re: 疑似手パ,中間報告
>プログラムの方ですけど、はっきりとは言えませんけど多分、再起動を繰り返すのだと思います。
今まで使っていた、秋月のPWMキットは、使っていて、感じた点があります。
それは、完全にON・OFFしない事。
その欠点とも思われる事は、秋月のPWMキット説明書にも、その旨の記載があります。
今回、自作、ま〜ガラクタですけど(笑い)
その辺の欠点を何とかと思った次第です。
それと、もう一点あります。
ボリュームの途中で、モーターが停止します。
これも何とかしたいのですが、何かいいアイデアありませんか?
PWMは、MACH3のボタン操作に伴い、SEC基板からの信号をPIC16F1827が受けて制御します。
AD変換する仕切り値といいうのかな〜、
仕切り値以上になったら、電圧の読み取り開始とか、
したらいいのでしょうか?
そうか、DUTYだ!
追記
Dutyを決めるCCPR1に最初から加算したら、どうかな?
+400 とか 500
動作速度から算出する。
今まで使っていた、秋月のPWMキットは、使っていて、感じた点があります。
それは、完全にON・OFFしない事。
その欠点とも思われる事は、秋月のPWMキット説明書にも、その旨の記載があります。
今回、自作、ま〜ガラクタですけど(笑い)
その辺の欠点を何とかと思った次第です。
それと、もう一点あります。
ボリュームの途中で、モーターが停止します。
これも何とかしたいのですが、何かいいアイデアありませんか?
PWMは、MACH3のボタン操作に伴い、SEC基板からの信号をPIC16F1827が受けて制御します。
AD変換する仕切り値といいうのかな〜、
仕切り値以上になったら、電圧の読み取り開始とか、
したらいいのでしょうか?
そうか、DUTYだ!
追記
Dutyを決めるCCPR1に最初から加算したら、どうかな?
+400 とか 500
動作速度から算出する。
Re: 疑似手パ,中間報告
PWMの動作開始を50%から出来たらいいな〜と、考えました。
そこで、プログラム真ん中辺りに、@ Aを書き加えました。
50%は、内部クロック1Mhzにしたので、
1/1000000 → 1サイクル時間は、1μs=1000ms
50%なら、500ms
ここから推測なのですが、
50%にしたいなら、CCPR1Lが500でいいと思いました。
如何でしょうか?
ご指摘願います。
宜しくお願いします。
/*PWMによりRB3で可変抵抗制御し、RB0を出力端子*/
//RB7がSEC基板ポート2のSL-13の1番ピン(出力端子)を入力端子として受ける
//その表示を操作盤のLEDでRA1から発光させる、また、基盤でもRA0からLEDにより発光させる
//PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
// 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 1000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を1MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00001000; // 可変抵抗の電圧読み込み用にRB3のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00001000; //RB3 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100101; // アナログ変換情報設定(AN9 RB3から読込む)
ADCON1 = 0b10010000; // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスとする
__delay_us(5); // アナログ変換情報が設定されるまでとりあえず待つ
//変数宣言
unsigned int num;//ADRESHの値
unsigned int duty;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
if(RB7==0){__delay_ms(10);break;}
LATA0=LATA1=RB7;//SEC基板ポート2のSL-13の1番ピン
num = adconv(); // RB3 9番ピン(AN9)から半固定抵抗の値を読み込む
@ duty=500+num;//Duty比50%からスタート
A if(duty > 500){
CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
CCP1CONbits.DC1B = num & 0b11;
__delay_ms(10);}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
APFCON0bits.CCP1SEL = 1; // RB0端子を出力端子に設定
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 255; //PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
そこで、プログラム真ん中辺りに、@ Aを書き加えました。
50%は、内部クロック1Mhzにしたので、
1/1000000 → 1サイクル時間は、1μs=1000ms
50%なら、500ms
ここから推測なのですが、
50%にしたいなら、CCPR1Lが500でいいと思いました。
如何でしょうか?
ご指摘願います。
宜しくお願いします。
/*PWMによりRB3で可変抵抗制御し、RB0を出力端子*/
//RB7がSEC基板ポート2のSL-13の1番ピン(出力端子)を入力端子として受ける
//その表示を操作盤のLEDでRA1から発光させる、また、基盤でもRA0からLEDにより発光させる
//PIC16F1827 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
// 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 1000000
// プロトタイプ宣言
void InitPWM(void);
void InitTimer2(void);
unsigned int adconv(void);
// メイン関数
void main(void) {
OSCCON = 0b0110101; //クロック周波数を1MHzに設定
PORTA = 0x00; //全てLo
PORTB = 0x00; //全てLo
ANSELA = 0b00000000; //全てデジタルI/Oとする
ANSELB = 0b00001000; // 可変抵抗の電圧読み込み用にRB3のみアナログ
// 入出力設定
TRISA = 0b00000000; // RA全て出力
TRISB = 0b00001000; //RB3 可変抵抗用ADC用入力端子
// ADコンバータ設定
ADCON0 = 0b00100101; // アナログ変換情報設定(AN9 RB3から読込む)
ADCON1 = 0b10010000; // 読取値は右寄せ、A/D変換クロックはFOSC/8、VDDをリファレンスとする
__delay_us(5); // アナログ変換情報が設定されるまでとりあえず待つ
//変数宣言
unsigned int num;//ADRESHの値
unsigned int duty;
// PWMモード設定関数の呼び出し
InitPWM();
// タイマ2設定関数の呼び出し
InitTimer2();
while (1) {
if(RB7==0){__delay_ms(10);break;}
LATA0=LATA1=RB7;//SEC基板ポート2のSL-13の1番ピン
num = adconv(); // RB3 9番ピン(AN9)から半固定抵抗の値を読み込む
@ duty=500+num;//Duty比50%からスタート
A if(duty > 500){
CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
CCP1CONbits.DC1B = num & 0b11;
__delay_ms(10);}
}
}
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
temp = ADRESH; //
temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
return temp; //読み込んだtempをnumに返す
}
// PWMモード設定関数
void InitPWM(void) {
APFCON0bits.CCP1SEL = 1; // RB0端子を出力端子に設定
// CCPのモードをPWMモードに設定
CCP1CONbits.CCP1M3 = 1;
CCP1CONbits.CCP1M2 = 1;
CCP1CONbits.CCP1M1 = 0;
CCP1CONbits.CCP1M0 = 0;
// 周期を255μ秒に設定(PR2 + 1μ秒)×1/(動作処理速度÷4)
PR2 = 255; //PR2レジスタ8bit0~255
// デューティーサイクルを0msで初期化
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}
// タイマ2設定関数
void InitTimer2(void) {
// プリスケーラ値を1に設定
T2CONbits.T2CKPS1 = 0;
T2CONbits.T2CKPS0 = 0;
// TMR2レジスタをクリア
TMR2 = 0;
// タイマ2起動
T2CONbits.TMR2ON = 1;
}
Re: 疑似手パ,中間報告
> その辺の欠点を何とかと思った次第です。
そのように、気にくわない部分を直していくのも良いと思います。
> ボリュームの途中で、モーターが停止します
これは単純に動き出す位置の問題ですよね?
前にも言ったと思いますけど、ボリューム位置をADCで取得しているのです。duty比を取得しているのではありません。
で、そのボリューム位置へ自由にduty比を割りづければ良いです。ただし、最低付近はキッチリ止めた方が良いです。(duty比0もしくはPWM停止)
止めなければモータが動かなくても電流が流れて発熱します。なので、ボリュームの10%?とか停止範囲を作った方が良いと思います。
※読み取りは全範囲します。というか、読み取らなければどの位置か判りません。
ツマミ位置が0-10%で停止。ツマミ位置10〜100%の位置で、使用する最低のちょっと下ぐらいのPWM〜100%PWMみたいな感じの割り付けになると思います。
スイッチ付のボリュームならちょっと違うと思います。
> @ duty=500+num;//Duty比50%からスタート
> A if(duty > 500){
> CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
> CCP1CONbits.DC1B = num & 0b11;
> __delay_ms(10);}
> }
Aがif文なのが判らないです。numが0の場合を除外したいのならもう少し範囲を確保した方が良いです。
テスターで電圧を測れば判ると思いますけど、一番下の桁はちょくちょく動きます。
そして、このコードだと上が切り取られる?(桁があふれる)のでちゃんと割合で合わせなければ駄目です。
そのように、気にくわない部分を直していくのも良いと思います。
> ボリュームの途中で、モーターが停止します
これは単純に動き出す位置の問題ですよね?
前にも言ったと思いますけど、ボリューム位置をADCで取得しているのです。duty比を取得しているのではありません。
で、そのボリューム位置へ自由にduty比を割りづければ良いです。ただし、最低付近はキッチリ止めた方が良いです。(duty比0もしくはPWM停止)
止めなければモータが動かなくても電流が流れて発熱します。なので、ボリュームの10%?とか停止範囲を作った方が良いと思います。
※読み取りは全範囲します。というか、読み取らなければどの位置か判りません。
ツマミ位置が0-10%で停止。ツマミ位置10〜100%の位置で、使用する最低のちょっと下ぐらいのPWM〜100%PWMみたいな感じの割り付けになると思います。
スイッチ付のボリュームならちょっと違うと思います。
> @ duty=500+num;//Duty比50%からスタート
> A if(duty > 500){
> CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
> CCP1CONbits.DC1B = num & 0b11;
> __delay_ms(10);}
> }
Aがif文なのが判らないです。numが0の場合を除外したいのならもう少し範囲を確保した方が良いです。
テスターで電圧を測れば判ると思いますけど、一番下の桁はちょくちょく動きます。
そして、このコードだと上が切り取られる?(桁があふれる)のでちゃんと割合で合わせなければ駄目です。
猛牛ロック 2018/12/27(Thu) 22:14 No.1378
Re: 疑似手パ,中間報告
猛牛ロックさん、有難うございます。
>※読み取りは全範囲します。というか、読み取らなければどの位置か判りません。
ツマミ位置が0-10%で停止。ツマミ位置10〜100%の位置で、使用する最低のちょっと下ぐらいのPWM〜100%PWMみたいな感じの割り付けになると思います。
スイッチ付のボリュームならちょっと違うと思います。
以下の部分が、電圧読み取りの部分ですが、@〜Fの間で細工するということでしょうか?
改善したい点は、現在、ボリュームが0〜50%に部分では動作しないので、
50%から動作開始としたいです。
// アナログ値の変換と読込み処理関数
@ unsigned int adconv() {
A unsigned int temp;
B GO_nDONE = 1; // アナログ値読取り開始指示
C while (GO_nDONE); // 読取り完了まで待つ
D temp = ADRESH; //
E temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
F return temp; //読み込んだtempをnumに返す
}
>※読み取りは全範囲します。というか、読み取らなければどの位置か判りません。
ツマミ位置が0-10%で停止。ツマミ位置10〜100%の位置で、使用する最低のちょっと下ぐらいのPWM〜100%PWMみたいな感じの割り付けになると思います。
スイッチ付のボリュームならちょっと違うと思います。
以下の部分が、電圧読み取りの部分ですが、@〜Fの間で細工するということでしょうか?
改善したい点は、現在、ボリュームが0〜50%に部分では動作しないので、
50%から動作開始としたいです。
// アナログ値の変換と読込み処理関数
@ unsigned int adconv() {
A unsigned int temp;
B GO_nDONE = 1; // アナログ値読取り開始指示
C while (GO_nDONE); // 読取り完了まで待つ
D temp = ADRESH; //
E temp = (temp << 8) + ADRESL; //RA3で読み込んだ値をtempに代入
F return temp; //読み込んだtempをnumに返す
}
Re: 疑似手パ,中間報告
AD変換のプログラムの内、@を追加したら、
ボリューム0でも、いきなり電圧が出てよくなったのですが、
不安定です。3,2V
ボリュームが悪いのかな〜、プログラムかな〜、どこが悪いのか分かりませんか?
皆様方宜しくお願いします。
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
@ if(ADRES > 300 ) {
temp = ADRESH; //上位8bit
temp = (temp << 8) + ADRESL; //RB3→RB4で読み込んだ値をtempに代入
return temp;} //読み込んだtempをnumに返す
}
ボリューム0でも、いきなり電圧が出てよくなったのですが、
不安定です。3,2V
ボリュームが悪いのかな〜、プログラムかな〜、どこが悪いのか分かりませんか?
皆様方宜しくお願いします。
// アナログ値の変換と読込み処理関数
unsigned int adconv() {
unsigned int temp;
GO_nDONE = 1; // アナログ値読取り開始指示
while (GO_nDONE); // 読取り完了まで待つ
@ if(ADRES > 300 ) {
temp = ADRESH; //上位8bit
temp = (temp << 8) + ADRESL; //RB3→RB4で読み込んだ値をtempに代入
return temp;} //読み込んだtempをnumに返す
}
Re: 疑似手パ,中間報告
こんな感じじゃないこと思います。
No.1377の@Aの部分に入れてください。
※ADCの値が50以上で動作。出力500(/1023)から。
if(num<50){
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}else{
num=(num-50)*(1023-500)/(1023-50)+500;
CCPR1L =num>>2 ;
CCP1CONbits.DC1B = num&3;
}
No.1377の@Aの部分に入れてください。
※ADCの値が50以上で動作。出力500(/1023)から。
if(num<50){
CCPR1L = 0;
CCP1CONbits.DC1B = 0;
}else{
num=(num-50)*(1023-500)/(1023-50)+500;
CCPR1L =num>>2 ;
CCP1CONbits.DC1B = num&3;
}
猛牛ロック 2018/12/28(Fri) 21:27 No.1381
Re: 疑似手パ,中間報告
猛牛ロックさん駄目です。
途中から2.2V位出てそのまま、ほぼ一定です。
まだ、No1380の方が良いです。
右肩上がりで、1.4V〜約4.2Vでます。
途中から2.2V位出てそのまま、ほぼ一定です。
まだ、No1380の方が良いです。
右肩上がりで、1.4V〜約4.2Vでます。
Re: 疑似手パ,中間報告
> @ duty=500+num;//Duty比50%からスタート
> A if(duty > 500){
> CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
> CCP1CONbits.DC1B = num & 0b11;
ちゃんと↑の4行をに変えましたか?
追伸
あぁ、多分桁あふれですね。
num=(num-50.0)*(1023-500)/(1023-50)+500;
でどうでしょう?
> A if(duty > 500){
> CCPR1L = num / 4; // アナログ値からのデータでデューティ値を設定
> CCP1CONbits.DC1B = num & 0b11;
ちゃんと↑の4行をに変えましたか?
追伸
あぁ、多分桁あふれですね。
num=(num-50.0)*(1023-500)/(1023-50)+500;
でどうでしょう?
猛牛ロック 2018/12/28(Fri) 22:20 No.1383
Re: 疑似手パ,中間報告
TRさん,猛牛ロックさん,こんばんは。
TRさん,いろいろがんばってられますね。
猛牛ロックさん,初歩的な質問ですけど,
PWMの制御に使う可変抵抗,AカーブとBカーブのもの,
どちらがいいのでしょうかね。
LEDの明るさとかではないので,普通Aカーブのもの
の方がいいのでしょうかね。
それとPWMの制御で,回転数を無段階に変更するよりも,
可変抵抗の読み取りを,あらかじめ作成しておいたテーブルに
したがって,振幅を決める,なんていう方法はどうなんでしょうか。
プログラムが煩雑になるかなあ・・・・・。
TRさん,いろいろがんばってられますね。
猛牛ロックさん,初歩的な質問ですけど,
PWMの制御に使う可変抵抗,AカーブとBカーブのもの,
どちらがいいのでしょうかね。
LEDの明るさとかではないので,普通Aカーブのもの
の方がいいのでしょうかね。
それとPWMの制御で,回転数を無段階に変更するよりも,
可変抵抗の読み取りを,あらかじめ作成しておいたテーブルに
したがって,振幅を決める,なんていう方法はどうなんでしょうか。
プログラムが煩雑になるかなあ・・・・・。
mabo 2018/12/29(Sat) 00:43 No.1384