トピック関連記事
48時間以内の記事は New Mark で表示されます
疑似手パ,中間報告
手パの経過報告です。
幾つかの問題に直面しました。
部材(スライドスイッチ)が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等で
の処理でしょうか。

それとも,一括で,ヘッダーフィアイルかんなんかにあるのでしょうか。
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、その他のライブラリでそれぞれ違いはあります。
どれも、その仕様に沿って書くことになります。)
猛牛ロック   2018/12/23(Sun) 23:09 No.1365
Re: 疑似手パ,中間報告
c言語 #include <USBComposite.h>

上記でネット検索しましたが、該当なし!
いや〜、難しいことやっていますね。


自分事ですが、最近、たてつづきに、制御関係のアクシデント
内、3件目は深刻です。

ポンプ制御に使っていた、秋月のPWMが壊れたようです。
出力端子から、全く電圧なし。

仕方がないので、とりあえず、写真の赤枠にある
秋月のPWMを買い替えます。

しかし、自分で作った赤枠以外のボードは、問題なし。

TR   2018/12/24(Mon) 08:08 No.1366
Re: 疑似手パ,中間報告
直接関係なくてすみません。

仮配線で秋月PWMに使われている発信用のIC555を試しました。
結果、発光せず。
どうも、これが駄目らしい。
一応、買い替えに決定しました。

TR   2018/12/24(Mon) 12:31 No.1367
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);
}

猛牛ロック   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の交換より,全体の買い換えの方が安くつくんでしょうかね。
mabo   2018/12/25(Tue) 21:04 No.1370
Re: 疑似手パ,中間報告
猛牛ロックさんのは、今はやりでしたか。
プログラムを見てもチンプンカンプンです。

IC555は秋月で。確か20円でした。
基板毎だと500円です。

一応、両方購入しました。

でも、FETとPICを使い、DCポンプを滑らかに回そうとしています。
でも、DC5V位から、一気に回ってしまう感じです。
ムズイ。
図面で一部誤り
GNDは、共通です。

TR   2018/12/25(Tue) 22:44 No.1371
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で還流されるので、ほぼサージが消えます。
猛牛ロック   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の言語じゃないのですか?



写真は、バラックでのテスト風景です。

TR   2018/12/26(Wed) 14:36 No.1373
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;
}
TR   2018/12/26(Wed) 20:47 No.1374
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出力あるいはアナログ入力になると思います。
私自身はプログラムが終わるコードを書いたことが無いので、当然、試したこともありません。
猛牛ロック   2018/12/26(Wed) 22:36 No.1375
Re: 疑似手パ,中間報告
>プログラムの方ですけど、はっきりとは言えませんけど多分、再起動を繰り返すのだと思います。


今まで使っていた、秋月のPWMキットは、使っていて、感じた点があります。
それは、完全にON・OFFしない事。
その欠点とも思われる事は、秋月のPWMキット説明書にも、その旨の記載があります。

今回、自作、ま〜ガラクタですけど(笑い)

その辺の欠点を何とかと思った次第です。

それと、もう一点あります。
ボリュームの途中で、モーターが停止します。
これも何とかしたいのですが、何かいいアイデアありませんか?

PWMは、MACH3のボタン操作に伴い、SEC基板からの信号をPIC16F1827が受けて制御します。

AD変換する仕切り値といいうのかな〜、
仕切り値以上になったら、電圧の読み取り開始とか、
したらいいのでしょうか?

そうか、DUTYだ!


追記
Dutyを決めるCCPR1に最初から加算したら、どうかな?
+400 とか 500
動作速度から算出する。
TR   2018/12/27(Thu) 07:00 No.1376
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;
}
TR   2018/12/27(Thu) 21:33 No.1377
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の場合を除外したいのならもう少し範囲を確保した方が良いです。
テスターで電圧を測れば判ると思いますけど、一番下の桁はちょくちょく動きます。
そして、このコードだと上が切り取られる?(桁があふれる)のでちゃんと割合で合わせなければ駄目です。
猛牛ロック   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に返す
}
TR   2018/12/28(Fri) 05:52 No.1379
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に返す
}
TR   2018/12/28(Fri) 13:32 No.1380
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;
}
猛牛ロック   2018/12/28(Fri) 21:27 No.1381
Re: 疑似手パ,中間報告
猛牛ロックさん駄目です。
途中から2.2V位出てそのまま、ほぼ一定です。

まだ、No1380の方が良いです。
右肩上がりで、1.4V〜約4.2Vでます。
TR   2018/12/28(Fri) 22:10 No.1382
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;
でどうでしょう?
猛牛ロック   2018/12/28(Fri) 22:20 No.1383
Re: 疑似手パ,中間報告
TRさん,猛牛ロックさん,こんばんは。

TRさん,いろいろがんばってられますね。

猛牛ロックさん,初歩的な質問ですけど,

PWMの制御に使う可変抵抗,AカーブとBカーブのもの,

どちらがいいのでしょうかね。

LEDの明るさとかではないので,普通Aカーブのもの

の方がいいのでしょうかね。


それとPWMの制御で,回転数を無段階に変更するよりも,

可変抵抗の読み取りを,あらかじめ作成しておいたテーブルに

したがって,振幅を決める,なんていう方法はどうなんでしょうか。

プログラムが煩雑になるかなあ・・・・・。
mabo   2018/12/29(Sat) 00:43 No.1384

処理 記事No 暗証キー

- JoyfulNote v6.02 -
++ Edited by Hamel ++