測距センサ
シャープの測距センサ(GP2Y0A21YK0F)の値をLPC1768のADで読み取りLEDを点灯させる。
#include "mbed.h" //----------------------------------------------------------- Serial pc(USBTX, USBRX); DigitalOut myled(LED1); //----------------------------------------------------------- class Led { public: Led() { led[0] = new DigitalOut(LED1); led[1] = new DigitalOut(LED2); led[2] = new DigitalOut(LED3); led[3] = new DigitalOut(LED4); } ~Led() { for(int i=0;i<4;i++){ delete led[i]; } } // level : 0 - 4 void indicator(int level) { switch(level){ case 0: *led[0] = 0; *led[1] = 0; *led[2] = 0; *led[3] = 0; break; case 1: *led[0] = 1; *led[1] = 0; *led[2] = 0; *led[3] = 0; break; case 2: *led[0] = 1; *led[1] = 1; *led[2] = 0; *led[3] = 0; break; case 3: *led[0] = 1; *led[1] = 1; *led[2] = 1; *led[3] = 0; break; case 4: *led[0] = 1; *led[1] = 1; *led[2] = 1; *led[3] = 1; break; } } void flasher() { for(int i=0;i<4;i++){ *led[i] = 1; wait(0.25); } for(int i=0;i<4;i++){ *led[i] = 0; wait(0.25); } }; private: DigitalOut *led[4]; }; //----------------------------------------------------------- class DistanceSensor { public: DistanceSensor(PinName in) { gp2y = new AnalogIn(in); }; ~DistanceSensor() { delete gp2y; }; uint16_t value(void) { return gp2y->read_u16(); }; private: AnalogIn *gp2y; }; //----------------------------------------------------------- int main() { Led leds; DistanceSensor *sensor = new DistanceSensor(P1_31); leds.flasher(); while(1) { uint16_t v = sensor->value(); pc.printf("DISTANCE : %d\n", v); int level = 0; if (v < 10000) level = 0; else if (v < 20000) level = 1; else if (v < 30000) level = 2; else if (v < 40000) level = 3; else level = 4; leds.indicator(level); wait(0.2); } }
素因数分解
素朴な素因数分解のHaskell版
Integerを使っているので桁数を気にしなくてよい。
-------------------------------------------------- -- factors.hs -------------------------------------------------- import System.Environment(getArgs) -------------------------------------------------- -- num : dividend -- i : first divisor -- return minimum factor -------------------------------------------------- findMinFactor :: Integer -> Integer -> Integer findMinFactor num i | (mod num i) == 0 = i | otherwise = findMinFactor num (i+1) -------------------------------------------------- -- num : dividend -- return : list of factors -------------------------------------------------- findFactors :: Integer -> [Integer] findFactors num | f == num = [num] | otherwise = f : findFactors (div num f) where f = findMinFactor num 2 -------------------------------------------------- -- argument : dividend -- print list of factors -------------------------------------------------- main = do arg1:rest <- getArgs let x = read arg1 :: Integer let factors = findFactors x print factors
素因数の素朴な求め方
C++で力技で素因数分解するプログラム
使用する場合はfactors(100)とかすれば、
コンソールに素因数が出力される。
再帰を使っているので、因数が多すぎるとスタックオーバーフローするかも。
数値はuint64_tを使っているので64bitまでが適用範囲。
#include "stdafx.h" #include <iostream> #include <stdint.h> #include <vector> // create a vector includes prime factors std::vector<uint64_t> *findPrime(uint64_t num) { for (uint64_t i = 2; i < num; i++) { if ((num % i) == 0) { std::vector<uint64_t> *vc; vc = findPrime(num / i); vc->push_back(i); return vc; } } std::vector<uint64_t> *v = new std::vector<uint64_t>(); v->push_back(num); return v; } int factors(uint64_t num) { std::cout << "--- " << num << " ---" << std::endl; std::vector<uint64_t> *v = findPrime(num); std::vector<uint64_t>::iterator it = v->begin(); while (it != v->end()) { std::cout << *it << " "; ++it; } std::cout << std::endl; return 0; }
自走式光追尾カー
CdSフォトトランジスタをサーボモータの上につけ、光の最も強い方向を探す。
見つけた方向に車体を回転させ、少し前進。
を繰り返し、光源に近づいていく。
#include "mbed.h" Serial pc(USBTX, USBRX); //----------------------------------------------------------- // CLASS for DC moter driver TA7291P class MoterDrive { public: MoterDrive(PinName in1, PinName in2) { mIn1 = new PwmOut(in1); mIn2 = new PwmOut(in2); mIn1->period(0.020); mIn2->period(0.020); }; ~MoterDrive() { delete mIn1; delete mIn2; }; // parameter degree takes the value -1.0 ^ 1.0 // 0.0 means stop // positive value means go forward // negative value means fo backward void run(double degree) { if (degree < -1.0) degree = degree < -1.0 ? -1.0 : degree; degree = degree > 1.0 ? 1.0 : degree; if (0.0 < degree){ // go forward mIn1->write(degree); mIn2->write(0.0); } else if (degree < 0.0){ // go back degree = fabs(degree); mIn1->write(0.0); mIn2->write(degree); } else { // degree == 0.0 , then stop mIn1->write(0.0); mIn2->write(0.0); } }; private: PwmOut *mIn1, *mIn2; }; //----------------------------------------------------------- // CLASS for servo moter SG90 class ServoMoter { public: ServoMoter(PinName in) { servo = new PwmOut(in); servo->period(0.020); }; ~ServoMoter() { delete servo; }; // parameter degree takes -90 ~ 90 // it represents axis // About SG90 // duty range is 0.5ms ~ 2.4ms corresponds to -90 degree to 90 degree. // especially, 1.45ms means 0 degree. // the relation degree and duty cycle is below. // y = (1.9/180)*x + 1.45 void run(int degree) { degree = degree < -90 ? -90 : degree; degree = degree > 90 ? 90 : degree; double duty = (1.9/180)*(double)degree + 1.45; servo->pulsewidth(duty/1000.0); }; private: PwmOut *servo; }; //----------------------------------------------------------- // CLASS for Photo register CDS MI5 series class PhotoRegister { public: PhotoRegister(PinName in) { photo = new AnalogIn(in); }; ~PhotoRegister() { delete photo; }; uint16_t value(void) { return photo->read_u16(); }; private: AnalogIn *photo; }; //----------------------------------------------------------- class CarControl { public: CarControl(MoterDrive *l, MoterDrive *r) { left = l; right = r; }; ~CarControl(){} void stop(void) { left->run(0.0); right->run(0.0); }; void forward(void) { left->run(degree); right->run(degree); }; void backward(void) { left->run(degree*(-1)); right->run(degree*(-1)); }; void rotate(int angle) { stop(); if(angle > 0){ left->run(degree); right->run(degree*(-1)); } else if(angle < 0){ left->run(degree*(-1)); right->run(degree); } double waitTime = ((double)abs(angle)) * rotateDeg; pc.printf("rotate time : %f\n", waitTime); wait(waitTime); stop(); }; private: MoterDrive *left, *right; static const double degree = 0.5; static const double rotateDeg = 0.02; }; //----------------------------------------------------------- class SearchLihgt { public: SearchLihgt(PhotoRegister *sensor, ServoMoter *servo) { pr = sensor; sm = servo; measures[0].angle = 90; measures[1].angle = -90; measures[2].angle = 75; measures[3].angle = -75; measures[4].angle = 60; measures[5].angle = -60; measures[6].angle = 45; measures[7].angle = -45; measures[8].angle = 30; measures[9].angle = -30; measures[10].angle = 15; measures[11].angle = -15; measures[12].angle = 0; }; ~SearchLihgt(){} int search(void) { int index; int maxCandidate = 0; uint16_t candidateValue = 0; for(index = 0;index<13;index++){ sm->run(measures[index].angle); wait(0.5); measures[index].value = pr->value(); if(measures[index].value > candidateValue){ maxCandidate = index; candidateValue = measures[index].value; } // pc.printf("search() %d : %d : %d\n", index, measures[index].angle, measures[index].value); } // pc.printf("Found min pos : %d\n", maxCandidate); sm->run(measures[maxCandidate].angle); return measures[maxCandidate].angle; }; struct pair { int angle; uint16_t value; }; struct pair measures[13]; private: PhotoRegister *pr; ServoMoter *sm; }; //----------------------------------------------------------- class Led { public: Led(PinName pin) { led = new DigitalOut(pin); *led = 0; state = 0; }; void toggle(void) { if (state == 0){ *led = 1; state = 1; } else{ *led = 0; state = 0; } }; private: DigitalOut *led; int state; }; //----------------------------------------------------------- void autoDrive(void) { MoterDrive *md1 = new MoterDrive(P2_1, P2_0); MoterDrive *md2 = new MoterDrive(P2_3, P2_2); ServoMoter *sm = new ServoMoter(P2_5); PhotoRegister *pr = new PhotoRegister(P1_31); CarControl *cc = new CarControl(md1, md2); SearchLihgt *sl = new SearchLihgt(pr, sm); Led *led = new Led(LED1); for(int count=0;;count++){ cc->stop(); int angle = sl->search(); wait(1.0); led->toggle(); pc.printf("DC_moter %d : %d\n", count / 100, angle); cc->rotate(angle); wait(1.0); led->toggle(); cc->forward(); wait(2.0); led->toggle(); } } //----------------------------------------------------------- int main() { autoDrive(); while(1){} }
LPC1768 モータドライブ
mbed LPC1768にモータドライバ()TA7291Pを接続。
可変抵抗の電圧をADで読み取り、TA7291Pの入力にPWMとして流し込む。
合わせ別のPWMでサーボモー^他の出力を生成。
結果、可変抵抗のつまみに応じてモーターの回転速度が変化し
サーボが動く。
#include "mbed.h" DigitalOut myled(LED1); PwmOut redLed(P2_5); PwmOut moterIN1(P2_1); PwmOut servo(P2_2); AnalogIn ain(A5); Serial pc(USBTX, USBRX); int main() { int count = 0; int ledOn = 0; redLed.period(0.020); moterIN1.period(0.020); servo.period(0.020); while(1) { double degree = ain; double value; value = 1.7*degree - 0.3; redLed.write(value); moterIN1.write(value); double y = 3.17*degree - 0.133; servo.pulsewidth(y/1000); if((count % 100) == 0){ pc.printf("DC_moter %d : %f : %f : %f\n", count / 100, degree, value, y); if(ledOn == 0){ myled = 1; ledOn = 1; } else{ myled = 0; ledOn = 0; } } wait(0.01); count++; } }
Debian8.2へのGuestAdditionのインストール
Debian8.2をnetinstでインストール。
その状態でGuestAdditionをインストールしようとすると失敗する。
/var/log/vboxadd-install.logには
unable to find the sources of your current Linux kernel.
のようにある。
GuestAdditionのインストールに必要なカーネルのヘッダなどをインストール
$ apt-get install dkms
$ apt-get install build-essential
$ apt-get install linux-headers-486
※linux-headers-486の486はアーキテクチャによってamd64 、 686-pae 、 486 などから選択。
その後、GuestAdditionのインストールを行えば成功。