月曜日, 10月 17, 2016

Karplus–Strongアルゴリズム

Karplus–Strongアルゴリズムというのがあります。ランダムなデータを減衰させながら一定の間隔でフィードバックしてやると音階となり、弦をはじいたような音がする、というものです。

ほんとかよ、というノリで音を合成してみました。これが案外きれいな音が出る。ハープシコードのような音が出ます。

ハープシコードの曲を聴きながらどんな旋律を弾かせようか考えたのですが、ここは純粋かつ簡素なかの曲を弾かせてみました。

この曲がいつまでも平和のシンボルであってほしいですね。

終わらないイラク戦争でミサイルで総攻撃をかけ、殺戮と破壊の「イラク軍」(+同盟軍)へ喝采を送る市民とかいうどこかの病んだ軍事大国はよくないと思います。

戦争でないと解決しないような不安定ないどうしようもない状態で、殺戮と破壊で即片が付くかといえばそんなことはありえないわけですが、後先考えない。目的が選挙であれば勝てればいいわけですね。イラクがどうなろうとそもそもイラクのためなのか議論さえなされない。

イラク戦争を終わらせるというのはそのものがスローガンだったのですが、戦争というのは始まると終わらない、わけですね。

// Audio.java -- a Karplus–Strong string synthesis implentation
// Copyright (c) 2016 easai
// Author: easai
// Created: Mon Oct 17 22:26:16 2016
// Keywords:
// Commentary:
// A random sequence is played at certain frequencies generates harpsichord-like sounds.
//
// Code:
import javax.sound.sampled.*;
import java.lang.Math;
public class Audio {
static final int freq=44100;// sampling rate
byte[] org=new byte[freq];
byte[] data=new byte[freq];
// play a note (picth = scale, length = len)
void note(SourceDataLine audio, int scale,double len)
{
double alpha=1.0;
for(int n=0;n<scale*len;n++)
{
for(int i=0;i<freq;i++){
data[i]=(byte)(org[i]*alpha);
}
audio.write(data, 0, (int)(freq/scale));
alpha*=.99;
}
}
public Audio(){
try{
AudioFormat fmt=new AudioFormat(freq, 8, 1, true, false);
SourceDataLine audio=(SourceDataLine)AudioSystem.getSourceDataLine(fmt);
audio.open(fmt);
audio.start();
// set random
for(int i=0;i<freq;i++){
org[i]=(byte)(Math.random()*256-128);
}
double scale[]={261.6, 293.7, 329.6, 349.2, 392.0, 440, 493.9, 523.3, 587.3, 659.3,698.5,784};
int index[]={1,0,1,2,4,2,1
,2,4,5,4,5,8,6,5,4
,2,4,5,8,7,8
,2,4,5,4,2,4,1
,5,7,8,7,8,5,4,5,4,2,1};
double len[]={1,1,1,1,1,1,2
,1,1,1,.5,.5,1,1,1,1
,1,1,2,1,1,2
,1,1,1,1,1.5,.5,2
,1,1,2,1,1,1,1,1,.5,.5,2};
for(int i=0;i<index.length;i++)
note(audio, (int)(scale[index[i]]),len[i]);
}catch(Exception e){
e.printStackTrace();
System.exit(1);
}
}
public static void main(String[] args){
new Audio();
}
}
// Audio.java ends here
view raw Audio.java hosted with ❤ by GitHub

土曜日, 10月 15, 2016

Arduino: 温度・湿度データロガー

ロボットを作るっていうのはエンジニアとしてはかなり究極な夢だと思います。

人間の能力を超えていてもいいんですが、発想というのはどうしても考える人間を基準としてしまうんですよね。

人らしさを備えたロボットっていうのは理想っぽいんではないかと思います。

あまり人間らしいと気味悪がられるわけですが、ちゃんとした研究があって、適度な人らしさというのがいいんだそうです。

でもここはロボットを作る(日本の)技術は人助けだといいたいですよね。

最新科学技術の粋であるところのロボットで人間らしさを取り戻す。

ここのところ米メディアで騒がれているロボットアームの技術というのがあります。

 まひした手にロボットアームで触覚を取り戻す! 米国防総省の研究機関が実験に成功

精巧なロボットアームと脳をつなぎ、失った腕の感覚を取り戻すという画期的な技術なわけですが、いいですね。

こういう研究があって、しかも政府とメディアが取り上げてくれる。エンジニアとしてはありがたい存在だと思います。



夢を大きく持ったところで、しまってあった Arduino を取り出して、温度・湿度データロガーを作ってみました。

... ちょっと格差が大きいですね。でもちゃんと出来たのでアップします。

/*
DHT11 temperature datalogger
[SD Card Module]
MOSI - pin 11
MISO - pin 12
SCL -- pin 13
CS --- pin 4
3.3 V
GND
[DHT11]
Data -- pin 5
Vcc
GND
*/
#include <SPI.h>
#include <SD.h>
#include <DHT.h>
#define CHIPSELECT 4
#define DHTPIN 5
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
unsigned long prev;
unsigned long start;
void setup() {
start = millis();
prev = start;
if (!SD.begin(CHIPSELECT)) {
return;
}
dht.begin();
}
void loop() {
unsigned long now = millis();
if (1000L * 30 < now - prev)
{
prev = now;
String dataString = "";
float h = dht.readHumidity();
dataString += String(h) + " %";
dataString += ", ";
float t = dht.readTemperature();
dataString += String(t) + " C";
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
}
}
}
view raw DHT11Logger.ino hosted with ❤ by GitHub

土曜日, 7月 09, 2016

Arduino: 赤外線距離センサー


赤外線距離センサーとは、赤外線LEDとフォトトランジスタを組み合わせ、反射してくる赤外線を測ることで距離を測るものです。



距離センサーというと超音波を使うものなどありますが、赤外線距離センサはまとめて売られている赤外線LEDとフォトトランジスタさえあればそのままセンサが量産できます。

LEDへの電流を制限する抵抗の値が小さいと発熱するので気を付ける必要があります。

人間の目は赤外線を検出できませんが、CCDであれば赤外線LEDが光っているのが分かります。



このセンサをモジュール化してみました。以下使ってみて気づいたことです。



このセンサは計測する物体が赤外線を反射しなければ使えません。白っぽければ反応しますが、そうでなければだめです。それはまだいいんですが…

このセンサーは赤外線を検出する方式ですので、赤外線がどこかほかからくればそれで反応します。つまり、太陽光のもとでは使えないってことです。

ライン・トレーサーなどで使われるのがこの赤外線距離センサーです。目的が限られてますね。注意しましょう。

木曜日, 7月 07, 2016

C++: べき集合の要素を数え上げる

べき集合というものがあります。部分集合の集合というものなんですが、べき集合の要素を出力するプログラムを書いてみました。

原理は簡単です。要素が n 個あるとして、含まれる場合を1、含まれない場合を0とすると

0 0 0
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1

これで完全な数え上げとなります。シフト演算子とか論理ANDとかを使うと、要素の数え上げができるわけですね。

では{ドイツ、フランス、英国}という集合を考えてみましょう。べき集合はこんなふうです。

{ }
{ Germany }
{ France }
{ Germany France }
{ United Kingdom }
{ Germany United Kingdom }
{ France United Kingdom }
{ Germany France United Kingdom }

すべてのケースを考えるというのはこの小さな集合だけでも大変ですね。

じゃあ、もう少し増やしてみましょう。イタリアとオランダ、スペインを加えてみました。

{ }
{ Germany }
{ France }
{ Germany France }
{ United Kingdom }
{ Germany United Kingdom }
{ France United Kingdom }
{ Germany France United Kingdom }
{ Italy }
{ Germany Italy }
{ France Italy }
{ Germany France Italy }
{ United Kingdom Italy }
{ Germany United Kingdom Italy }
{ France United Kingdom Italy }
{ Germany France United Kingdom Italy }
{ Netherlands }
{ Germany Netherlands }
{ France Netherlands }
{ Germany France Netherlands }
{ United Kingdom Netherlands }
{ Germany United Kingdom Netherlands }
{ France United Kingdom Netherlands }
{ Germany France United Kingdom Netherlands }
{ Italy Netherlands }
{ Germany Italy Netherlands }
{ France Italy Netherlands }
{ Germany France Italy Netherlands }
{ United Kingdom Italy Netherlands }
{ Germany United Kingdom Italy Netherlands }
{ France United Kingdom Italy Netherlands }
{ Germany France United Kingdom Italy Netherlands }
{ Spain }
{ Germany Spain }
{ France Spain }
{ Germany France Spain }
{ United Kingdom Spain }
{ Germany United Kingdom Spain }
{ France United Kingdom Spain }
{ Germany France United Kingdom Spain }
{ Italy Spain }
{ Germany Italy Spain }
{ France Italy Spain }
{ Germany France Italy Spain }
{ United Kingdom Italy Spain }
{ Germany United Kingdom Italy Spain }
{ France United Kingdom Italy Spain }
{ Germany France United Kingdom Italy Spain }
{ Netherlands Spain }
{ Germany Netherlands Spain }
{ France Netherlands Spain }
{ Germany France Netherlands Spain }
{ United Kingdom Netherlands Spain }
{ Germany United Kingdom Netherlands Spain }
{ France United Kingdom Netherlands Spain }
{ Germany France United Kingdom Netherlands Spain }
{ Italy Netherlands Spain }
{ Germany Italy Netherlands Spain }
{ France Italy Netherlands Spain }
{ Germany France Italy Netherlands Spain }
{ United Kingdom Italy Netherlands Spain }
{ Germany United Kingdom Italy Netherlands Spain }
{ France United Kingdom Italy Netherlands Spain }
{ Germany France United Kingdom Italy Netherlands Spain }

そうですね。どのような通商交渉が成り立つでしょうか。

では極め付け、EUが存在しないと仮定して、EU加盟国の各国のそれぞれ組み合わせを考えたとします。

と、書きだそうとするとファイルの大きさがギガを超えてきたのでギブアップです。

組み合わせを考えるとなんと 268435456 となります。

これを考えるとEUのフレームワークってのは偉大ですね。

あらたな世界秩序ってのをつくろう、ってのは無謀じゃないでしょうか。

#include <iostream>
using namespace std;
int main()
{
string set[]={
"Germany",
"France",
"United Kingdom",
"Italy",
"Netherlands",
"Spain"
};
/*
string set[]={
"Austria",
"Belgium",
"Bulgaria",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Estonia",
"Finland",
"France",
"Germany",
"Greece",
"Hungary",
"Ireland",
"Italy",
"Latvia",
"Lithuania",
"Luxembourg",
"Malta",
"Netherlands",
"Poland",
"Portugal",
"Romania",
"Slovakia",
"Slovenia",
"Spain",
"Sweden",
"United Kingdom"
};
*/
int n=sizeof(set)/sizeof(set[0]);
for(int i=0;i<(1<< n);i++)
{
cout << "{ ";
for(int j=0;j<n;j++)
{
if(((i>>j)&1)==1)
{
cout << set[j] << " ";
}
}
cout <<"}"<< endl;
}
return 0;
}
view raw powerset.cpp hosted with ❤ by GitHub

水曜日, 7月 06, 2016

C++: 逆ポーランド記法

数式の表現方法で、ポーランド記法ってのがあります。

普通の数式では

a + b

と書くところを、演算子(プラス記号)の順序を変えて、

+ a b

と書きます。

これだって数式は表せるわけですね。Lisp などでは (+ a b) となります。

+ + a b c

これだと、どうなるでしょう。

a + b + c

こうですね。

逆ポーランド記法というのあります。逆ポーランド記法であると、a + b が

a b +

となります。日本語だと思えばいいんですね。「a と b を足す」という形です。

a b c + +

これだと、「a と b と c と足して、また足す」となります。

以下は、逆ポーランド記法の数式を処理するプログラムです。

→  reverse-polish-notaion

#括弧の処理を追加しました。(2016-07-10)


#include <iostream>
#include <sstream>
#include <stack>
#include <stdlib.h>
using namespace std;
string parse()
{
string str;
stack<string> stk;
char c;
int x,y,z;
while(cin >> c, c != '=')
{
switch(c)
{
case '(':
stk.push(parse());
break;
case ')':
if(!stk.empty())
{
return stk.top();
}
break;
case '+':
case '*':
case '-':
case '/':
x=atoi(stk.top().c_str());stk.pop();
y=atoi(stk.top().c_str());stk.pop();
if(c=='+')
z=x+y;
else if(c=='-')
z=y-x;
else if(c=='*')
z=x*y;
else if(c=='/')
{
if(x!=0)
z=y/x;
else
{
cout << "Error: Division by zero" << endl;
throw 0;
}
}
stk.push(static_cast<ostringstream*>( &(ostringstream() << z) )->str());
break;
default:
cin.putback(c); cin >> str;
stk.push(str);
break;
}
}
if(!stk.empty())
{
return stk.top();
}
throw 0;
}
int main()
{
try
{
cout << parse();
}
catch(int e)
{
cout << "Parse error" << endl;
}
return 0;
}
view raw calc.cpp hosted with ❤ by GitHub

月曜日, 7月 04, 2016

g++: テンプレートを使う場合の分割コンパイル

テンプレートを使う場合、実装を別ファイルで行うとややこしくなります。

こんなテンプレートを使うヘッダーファイルがあったとします。

template <class T> class A
{
public:
int a;
A();
};
view raw header.h hosted with ❤ by GitHub

ここで、別ファイルで実装します。

#include "header.h"
template <class T> A<T>::A()
{
a=0;
}
view raw a.cpp hosted with ❤ by GitHub

このヘッダーファイルをインクルードして、別ファイルで呼び出すとリンカがエラーを出します。

#include <iostream>
#include "header.h"
using namespace std;
int main()
{
A<int> a;
cout << a.a << endl;
return 0;
}
view raw main.cpp hosted with ❤ by GitHub

ヘッダーファイルで実装すると問題は解決です。

template <class T> class A
{
public:
int a;
A()
{
a=0;
}
};
view raw header-new.h hosted with ❤ by GitHub

水曜日, 6月 29, 2016

C/C++ GMP ライブラリを使う(Java でいう BigInteger です)

とても大きな数を扱うとき、Java では BigInteger などを使うと制限なしです。しかも標準装備。

ここで扱いたい大きな数というのは、ほかでもないメルセンヌ素数です。とんでもなく大きな数となるのでどうしてもライブラリを使う必要があります。

ほかでもないというのは、メルセンヌ素数という形であれば素数であるかの判定が容易という理由から、発見された最大の素数はメルセンヌ素数であるからです。

// Mersenne.java -- Calculate Mersenne prime number
// Copyright (c) 2016 easai
// Author: easai
// Created: Wed Jun 29 20:56:11 2016
// Keywords:
// Commentary:
// Compile as (does not require any additional library):
// javac Mersenne.java
//
// Run as:
// java Mersenne n
// Code:
import java.math.*;
import java.io.*;
public class Mersenne
{
public static BigInteger mersenne(int p)
{
return (BigInteger.ONE.shiftLeft(p)).subtract(BigInteger.ONE);
}
public static void main(String args[])
{
int n=1;
try
{
if(args.length==0)
{
System.out.print("Enter a number: ");
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
String str=reader.readLine();
n=Integer.parseInt(str);
}
else
{
n=Integer.parseInt(args[0]);
}
BigInteger mp=mersenne(n);
System.out.println(mp);
}
catch(Exception e){e.printStackTrace();}
}
}
// Mersenne.java ends here
view raw Mersenne.java hosted with ❤ by GitHub
このプログラムをCで実装しようとすると、GMPなど外部ライブラリが必要となります。GMPを使ったソースです。

// mersenne.cpp -- Calculate Mersenne prime number
// Copyright (c) 2016 easai
// Author: easai
// Created: Wed Jun 29 20:53:34 2016
// Keywords:
// Commentary:
//
// Compile as (requires gmp library):
// gcc mersenne.c -lgmp
//
// Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <gmp.h>
void mersenne(mpz_t r, int p)
{
mpz_ui_pow_ui(r,2,p);
mpz_sub_ui(r,r,1);
}
int main(int argc, char* argv[])
{
int nopt=0;
char *nparam=NULL;
int opt;
while((opt=getopt(argc, argv, "h"))!=-1) {
switch(opt){
case 'h':
printf("Usage: mersenne n\n");
break;
}
}
int n;
if(optind < argc)
{
n=atoi(argv[optind]);
mpz_t t;
mpz_init(t);
mersenne(t,n);
gmp_printf("%Zd \n",t);
mpz_clear(t);
}
return 0;
}
// mersenne.cpp ends here
view raw mersenne.c hosted with ❤ by GitHub
このプログラムもC++を使うと分かりやすくなります。初期化、後始末などコンストラクタ、デストラクタで書けるからです。

// mersenne.cpp -- Calculate Mersenne prime number
// Copyright (c) 2016 easai
// Author: easai
// Created: Wed Jun 29 20:53:34 2016
// Keywords:
// Commentary:
//
// Compile as (requires gmp library):
// g++ mersenne.cpp -lgmpxx -lgmp
//
// Code:
#include <unistd.h>
#include <gmpxx.h>
#include <iostream>
using namespace std;
mpz_class mersenne(int p)
{
mpz_class mp;
mpz_ui_pow_ui(mp.get_mpz_t(),2,p);
mp--;
return mp;
}
int main(int argc, char* argv[])
{
int nopt=0;
char *nparam=NULL;
int opt;
while((opt=getopt(argc, argv, "h"))!=-1) {
switch(opt){
case 'h':
printf("Usage: mersenne n\n");
break;
}
}
int n;
if(optind < argc)
{
n=atoi(argv[optind]);
mpz_class mp=mersenne(n);
cout << mp;
}
return 0;
}
// mersenne.cpp ends here
view raw mersenne.cpp hosted with ❤ by GitHub

C#だとこんな感じでしょうか。

// Mersenne.cs -- Calculate Mersenne prime number
// Copyright (c) 2016 easai
// Author: easai
// Created: Wed Jun 29 20:53:34 2016
// Keywords:
// Commentary:
//
// Tested with VC++ 2015
//
// Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
namespace Prime
{
class Program
{
static BigInteger mersenne(int p)
{
BigInteger mp = 1;
mp = (mp << p) - 1;
return mp;
}
public static bool isPrime(BigInteger n)
{
bool isPrime = true;
BigInteger max = n;
BigInteger i = 1;
while (i < max)
{
if (i != 1 && (n % i) == 0)
{
isPrime = false;
break;
}
max = n / i;
i++;
}
return isPrime;
}
static void Main(string[] args)
{
int[] p = { 2, 3, 5, 7, 13, 17, 19, 31 };
for(int i=0;i<p.Length;i++)
{
BigInteger mp=mersenne(p[i]);
if (isPrime(mp))
Console.WriteLine(mp + " is a prime");
else
Console.WriteLine(mp + " is not a prime");
}
}
}
}
// Mersenne.cs ends here
view raw Mersenne.cs hosted with ❤ by GitHub

火曜日, 6月 21, 2016

Arduino ISP: ATTiny13A でサイコロを回す



ATtiny13A でサイコロを回そうと思えば rand() 関数が大きいようです。ここは自分で組まねばなりません。

乱数といえば線形合同法だと思えば、Xorshift なる計算方法が流行ってるんですねえ。

高速かつ長周期、じゃあということで Xorshift へ乗り換えて作ってみました。

マシンで合成する疑似乱数ってのは「疑似」乱数なのであってパターンが決まっています。ある一定の周期を持つわけです。長ければ長いほどいい乱数です。あとは出てくる値が均一でないとなりません。

メルセンヌ・ツイスタをすすめる向きもあるようですが、ここでは Xorshift で。

あとシードが必要なんですが、タイマーを使ったりメモリを読んだり、空ピンの値を読んだりするのがベスト・プラクティスなようです。ここではスイッチでの割り込み時のカウンタの値を使ってみました。

/*
* Dice.cpp
*
* Created: 2016-06-21
* Author : easai
*/
#include <avr/io.h>
#include <avr/interrupt.h>
int digit[6] = {
0b10000,
0b01000,
0b11000,
0b01100,
0b11100,
0b01101
};
volatile unsigned long r;
volatile unsigned long timer_counter=0;
int interval=1000;
volatile unsigned int counter=0;
ISR(TIM0_OVF_vect)
{
timer_counter++;
if((timer_counter%interval)==0)
{
if(counter < 50)
{
// Xorshift
r = r ^ (r << 13);
r = r ^ (r >> 17);
r = r ^ (r << 5);
// LCG
// r=(r*109+89)%251;
PORTB = digit[r%6];
counter++;
}
else if(counter < 100)
{
PORTB = digit[r%6];
counter++;
}
else
{
PORTB = 0;
}
}
}
ISR(INT0_vect)
{
cli();
counter=0;
r=timer_counter;
sei();
}
int main(void)
{
DDRB |= 0b11101;
PORTB = 0;
TCCR0A=0;
TCCR0B=(1<<CS00);
TIMSK0|=(1<<TOIE0);
MCUCR |= (1<<ISC01);
GIMSK |= (1<<INT0);
sei();
timer_counter=0;
counter=100;
while (1) {}
}
view raw Dice.cpp hosted with ❤ by GitHub

金曜日, 6月 17, 2016

Imref とは?(フェルミ準位の話です)

英国のEU脱退の話ですね?

EUが崩壊するのか、英国が崩壊するのか。西洋社会が崩壊するのか。

世界経済が崩壊するとなんですがね。

規制緩和、プライマリーバランス。官僚の無駄遣い。よく理解できますよね。EUってのね。

しかしですよ、英国がEU脱退すると影響力とかってなくなるわけですよね。

突っ走るEUとか、米国のポチと成り果てる英国とか。

閑話休題。

オンラインで電子工学の授業を視聴していたら、imref って単語が出てきました。

新しい単位でも定義したのかと思うと、この単語よくよく見てみると...

Fermi だっていうんですよ。フェルミ準位の Fermi です。で、imref が何かといえばこの Fermi の逆。逆読みだっていうんですね。

分からないものですね。一見まったく別の単語としか見えない。疑フェルミ準位を表すものだそうです。不純物が入るとフェルミ準位がずれるのでその値です。

ということで、文字を反転するプログラムを書いてみました。

まずは Elisp で。

(defun reverse-word(str)
"Reverse the given string"
(interactive "sWord:")
(eval (cons 'concat (reverse (mapcar (lambda(x) (string x)) str)))))
;(reverse-word "fermi")
(defun _reverse(lst)
"Reverse the given list"
(if (= (length lst) 1)
lst
(append (_reverse (cdr lst)) (list (car lst)))))
;(_reverse '( a b c d e))
(defun reverse-region(start end)
"Reverse text in the region"
(interactive "r")
(insert (reverse-word (buffer-substring-no-properties start end)))
(kill-region start end))
;edcba
;(apply 'string (scramble "abcdef"))
(defun scramble (str)
"Scramble the word specified"
(shuffle-list str))
(defun shuffle-list (str)
"Return random ordered list."
(let* ((lst (string-to-list str))
(len (length lst))
(r (random len)))
(if (< len 1)
nil
(cons (nth r lst)
(scramble (append (head r lst)(nthcdr (1+ r) lst)))))))
view raw scrambled.el hosted with ❤ by GitHub
こちらは C++(g++)。

#include<string>
#include<iostream>
using namespace std;
int main()
{
string str;
cout << "Enter a word: ";
cin >> str;
int n=str.length();
for(int i=0;i<n;i++)
{
cout << str[n-i-1];
}
cout << endl;
return 0;
}
view raw reverse.cpp hosted with ❤ by GitHub
ついでといえばなんですが、じゃあということで反転だけじゃなくて文字列をスクランブルするプログラムを書いてみました。

#include <climits>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
using namespace std;
string scramble(string str)
{
int n=str.length();
string res="";
int filled[n];
for(int i=0;i<n;i++)
filled[i]=0;
for(int i=0;i<n;i++) {
int r=rand() % (n-i);
int j=0;
int count=0;
do {
if(filled[j]==0) {
if(r<=count) {
filled[j]=1;
break;
}
count++;
}
}
while(++j<n);
res+=str[j];
}
return res;
}
long factorial(int n)
{
long res;
if(n==1)
res=n;
else
res=n*factorial(n-1);
return res;
}
int main(int argc, char* argv[])
{
string str;
srand(time(NULL));
int nopt=0;
char *nparam=NULL;
int opt;
while((opt=getopt(argc, argv, "n:"))!=-1) {
switch(opt){
case 'n':
nopt=1;
nparam=optarg;
break;
}
}
int n=INT_MAX;
if(nopt==1)
{
n=atoi(nparam);
}
if(optind < argc)
{
str=scramble(argv[optind]);
}
else
{
cout << "Enter a word: ";
cin >> str;
}
int len=str.length();
int n_res=min((int)factorial(len),n);
string resList[n_res];
for(int i=0;i<n_res;i++)
{
bool duplicate=true;
string new_str="";
while(duplicate){
new_str=scramble(str);
duplicate=false;
for(int a=0;a<i;a++)
{
if(resList[a].compare(new_str)==0)
{
duplicate=true;
break;
}
}
}
resList[i]=new_str;
}
for(int i=0;i<n_res;i++)
cout << resList[i] << endl;
return 0;
}
view raw scramble.cpp hosted with ❤ by GitHub


乱数を計算する回数を減らすよう乱数を出してからはじくのではなく、必要な分だけ計算し文字列から選んでいます。

金曜日, 6月 03, 2016

Arduino ISP: ATtiny 割り込み・PWM

Arduino ISP を使うと ATtiny13A をそのままプログラムできます。そのままというのは、Arduino IDE を介さないでってことです。ライブラリを使わず書くと、プログラムサイズを小さくできます。

pinMode(), digitalWrite() などは使えず、マイクロコントローラのレジスタなど設定せねばなりません。pinMode() は DDRB レジスタ、digitalWrite() は PORTB などのレジスタを設定することで実装できます。

割り込みなどは MCUCR, GIMSK レジスタを設定し、割り込みを許可せねばなりません。

/*
* Interrupt.cpp
*
* Created: 6/2/2016 5:05:28 PM
* Author : easai
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
ISR(INT0_vect)
{
PORTB |= (1<< DDB0);
_delay_ms(10000);
PORTB &= ~(1<< DDB0);
}
int main(void)
{
DDRB |= (1<<DDB0);
MCUCR |= (1<<ISC01);
GIMSK |= (1<<INT0);
sei();
while (1){}
return 0;
}
view raw Interrupt.cpp hosted with ❤ by GitHub
参照:ピン入力と割り込み


ATtiny13A では PWM 出力が可能ですが、これも TCCR0A, TCCR0B レジスタを設定し、デューティ比を OCR0A, OCR0B などで設定します。


/*
* PWM.cpp
*
* Created: 6/3/2016 8:59:58 AM
* Author : easai
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB |= 0b00011;
TCCR0A = (1<<COM0A1) | (1<< COM0B0) | (1<< COM0B1) | (1 << WGM01) | (1 << WGM00);
OCR0A = 0;
OCR0B=0;
TCCR0B = (1<<CS00);
while (1)
{
OCR0A+=10;
if(255<=OCR0A)
{
OCR0A=0;
}
OCR0B=OCR0A;
_delay_ms(500);
}
return 0;
}
view raw PWM.cpp hosted with ❤ by GitHub
参照:PWMについて調べて、リモコン信号出力してみた。(ATtiny13A) 


ATtiny13A の良さといえば、省電力で省スペース、低価格であること。活用しましょう。

日曜日, 5月 29, 2016

Arduino as ISP: ATtiny13A ヒューズ・リセッター

ATtiny13A というマイクロコントローラICがあります。

このたびこいつを Arduino でどうにかプログラミングすることができたので経緯を記しておきます。すったもんだしたあげくいろいろなものを壊した気がします。というのは、ヒューズの設定で動いてくれなかったからです。

わかってみるとなんですが、この入手したチップ、内部クロック用ヒューズが工場出荷時の値(0x6a, 0xff)ではなかったわけなんです(データシート)。これが原因だと分かるまで時間がかかりました。まずは表面実装部品を使ったのが苦労の発端。

使い慣れない部品を使って新しいことをやろうというのは不確定要素が重なって原因への追及への困難が増します。気を付けましょう。SOP8変換ボードが悪いのか、はたまた設定のせいなのか、そもそも不可能を試みているのかわからないからです。

自作のヒューズ・リセッタ


結論をいうと、Arduino IDE 1.6.x で ATtiny13A をプログラムすることができました。ただし、ヒューズのリセッタを作成する必要がありました。以下のサイトを参照させていただきました。

Arduino UNOでATTiny開発してるときに書き込めない!AVR壊れた!?その前に
Attiny13をArduino化 ついでに外部クロック
AVRマイコンを Arduino-IDE 1.6.x で使用する方法

リセットされれば標準的な?やり方でプログラムできます。

まず File | Examples | 11. ArduinoISP メニューから ArduinoISP をアップロードします。ロード出来たらライタ・シールドを接続し、ATtiny をセットします。青いLED が点滅すれば準備ができています。Tools|Board を ATtiny13 、Tools|Programmer を Arduino as ISP を設定します。そしてプログラムをアップロード。


Attiny 自作ライタ・シールド

ATtiny13A でフルカラーLEDを動かしてみました。


月曜日, 5月 23, 2016

Arduino: チップ部品を使う・時計を動かす

挑戦してみました。表面実装(チップ部品)。安い、小さい、軽い、将来性ってことで、使えなきゃいけないとは思ってはいたのですが、変換ボードさえあればブレッドボードで動きます。


まずは変換ボード。これがないと始まらない、というか部品が宝の持ち腐れとなってしまいます。この変換ボードが今日やっと届きました。待ち遠しかったですね。


こいつの作り方のコツはきっちり手順を踏むことですね。手順を踏まないといろいろ壊れます。まずピン足への線が細かくて切れます。パターンが熱で外れます。ブリッジができます。なんかいくつも壊した気がします。

以下手順です。

ブレッドボードを利用してピン足をはんだ付けする。これで固定できます。はんだをチップ部品のパターンへ薄く流す。チップをピンセットでつかみ、薄くついたはんだを溶かしながらチップを固定する。

薄くはんだを置いて部品を固定し、ブリッジができないよう各ICピンをはんだ付けしていくわけです。ここは細かい作業なので神経を使います。導通チェックでよくよく見ていくとつながってなかったなんてことがあるわけですね。接続はきちんと調べましょう。

このSOP8のICは時計用のICで、時計用のクリスタルを接続すると時計として使えます。プロトコルが特殊ですが、Arduino 本家のサイトのコードを使うと時間をきちんと読み込んでくれました。

これでチップ部品が使えます。

土曜日, 5月 21, 2016

(Arduino): ESP8266 を USB シリアル通信変換器 FTDI でつなぐ

WiFi モジュール ESP8266 というのがあります。無線LANとつなげるというのがウリですが、Arduino との連携がよくない。ともかく USB シリアル通信変換器 FTDI で PC とつないでみました。


ESP8266 のピン配置は以下の通り。

Rx Vcc
GPIO Reset
CPIO CH_PD
GND Tx

あとは FTDI と WiFiモジュールをつなぎます。





長足のピンヘッダーを使うとうまくブレッドボードを使えます。

Vcc, GND
Rx - Tx
Tx - Rx
pull-up CH_PD

PC とつなぐにはまず FTDI のドライバをダウンロードします。

 
あとこれ引っかかりやすいですが、デバイスマネジャーで通信速度を設定します。

Arduino IDE を立ち上げて、ポートを設定、シリアルモニターを起動して通信速度を設定し、モジュールをつなぎます。

AT とコマンドを打つと OK と返ってくるはずです。
 

画像は AT+GMR コマンドの結果を示しています。

水曜日, 5月 18, 2016

Arduino: シリアル通信(IIS)

Arduino Uno はそこそこピン数があります。7セグでもつなげてしまうほどピン数が多いわけですが、線の多いのは困りものです。場所を取るし配線がやっかいです。配線が多いのはうざいってだけではなく、配線を調べねばならないというだけで作ろうという雰囲気をぶち壊してくれます。

そこでシリアル通信なる方法を使います。効率よくデータを送受信できます。Arduino 用モジュールとして売られているセンサーなどはそもそもシリアル通信でのみ通信できるようなものも多いです。

先日頼んでおいた加速度センサーでシリアル通信(IIC)を使ってデータを読み込んでみました。Arduino 標準の Wire.h ライブラリを使ってアドレスを指定し、データを読み込みます。配線は Vcc (5V), GND, SDA (Pin 4), SCL (Pin 5), CS (5V)。


アドレス、モード指定、レジスタ番地などはデータシートなどを参照する必要があります。ここで引っかかったのはモード指定で、データシートを見ても指定しなければならないということがなかなか読めない。

書き込みは多いモジュールなので、どうやら動くよう設定することができました。以下コードです。

#include <Wire.h>
#define addr 0x53
void setup()
{
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(addr);
Wire.write(0xA7);
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.write(0x2D);
Wire.write(0x0);
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.write(0x2D);
Wire.write(0x10);
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.write(0x2D);
Wire.write(0x8);
Wire.endTransmission();
}
void loop()
{
int x,y,z;
Wire.beginTransmission(addr);
Wire.write(0x32);
Wire.endTransmission();
Wire.requestFrom(addr,6);
if(6<=Wire.available())
{
x=Wire.read() << 8;
x|=Wire.read();
y=Wire.read() << 8;
y|=Wire.read();
z=Wire.read() << 8;
z|=Wire.read();
}
Serial.print("X =");
Serial.println(x);
Serial.print("Y =");
Serial.println(y);
Serial.print("Z =");
Serial.println(z);
Serial.println();
delay(500);
}

日曜日, 5月 15, 2016

Arduino: 7セグ時計

有機ELディスプレイってのはいいです。小さいのがいい。薄くて軽くて電池の持ちがいい。バックライトのいらない発光素子ってのはいいです。暗闇でも見えるし、それでいて消費電力が少ない。

しかしながらまだ高いのが難点です。そこで価格の安い7セグを使ってみました。7セグなら暗闇でもくっきりはっきりそれなりの雰囲気があります。


ここでは4桁の7セグを直接 Arduino とつないでみました。各セグメントへ7+1ピン、各桁へピンが4つ、あとは GND をつなぎます。注意せねばならないのは、この7セグはカソードコモンなのでドライバ用のトランジスタがGND側で必要だということです。

あとはパターンをセグメントへ送ればいいわけですが、各桁ごとパターンを消去、そしてパターンを送るというプロセスを繰り返します。書き込んで間をおかないとうまく表示されません。

空いているピンでクロック・モジュールを読み込んでいます。

まずはブレッドボードで組んでみたのですが配線が多い。のでモジュールを作ってみました。

digitalWrite() を使ってひとつひとつ書いていくと画面がちらつくので、ポートレジスタへ直接データを書き込んでみました。



コードはこちらです。

/*
* Clock.cpp
*
* Created: 2016-06-21
* Author : easai
*/
#include <DS3231.h>
//DS3231 rtc(SDA, SCL);
DS3231 rtc(SCL, SDA);
Time t;
int seven_segment[] = {
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0x0
};
int dot = 0b10000000;
int digit[] = {
0b00000010, 0b00000100, 0b00001000, 0b00010000
};
int pause = 4;
void setup() {
DDRD = 0b11111111;
PORTD = 0;
DDRB = 0b00011110;
PORTB = 0;
rtc.begin();
}
void loop() {
t = rtc.getTime();
PORTD = seven_segment[t.min % 10];
PORTB = digit[3];
delay(pause);
PORTD = seven_segment[(t.min / 10) % 10];
PORTB = digit[2];
delay(pause);
PORTD = seven_segment[t.hour % 10];
PORTB = digit[1];
delay(pause);
if (10 <= t.hour)
{
PORTD = seven_segment[(t.hour / 10) % 10];
PORTB = digit[0];
delay(pause);
}
PORTD |= dot;
}
view raw Clock.ino hosted with ❤ by GitHub

木曜日, 4月 28, 2016

Arduino: 温度湿度センサー DHT11

温度湿度センサー DHT11 が今日届きました。

中国からだといつ届くかわからないこの意外性が贈り物みたいでいいですね。

このセンサー精度がどうとかいう記述があって、迷っていたのですが結局買ってしまいました。

いいですね。きちんと動きます。Arduino のおかげです。書き込みが多くて世界中の人間が使っているのが分かります。

ピン配置は左から Vcc, Data, NC, GND です。5k ほどのプルアップ抵抗が必要です。

ライブラリをダウンロードして、読み込むときちんと表示されました。もちろん、配線を間違えると動きません。アナログ入力ピンなどとつなぐとだめです。


 読み込めてうれしいところでくだんの有機ELディスプレイとつないでみました。

このハードルの低さ。情報の多さ、完成度の高さ。Arduino ですね。

#include <dht.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
dht DHT;
#define DHT11_PIN 5
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
}
void loop() {
display.setCursor(0, 0);
int chk = DHT.read11(DHT11_PIN);
if (chk == DHTLIB_OK)
{
display.clearDisplay();
display.println("Humidity: " + String(DHT.humidity) + " %");
display.println("Temperature: " + String(DHT.temperature) + " C");
}
else
{
display.println("Hello DHT11");
}
display.display();
delay(2000);
}
view raw DHT11.ino hosted with ❤ by GitHub

ブレッドボードでは心もとないので、DHTモジュールをつくっておきました。あとはいつもの百均ケースで収まってくれました。

水曜日, 4月 27, 2016

PowerBuilder: 変数名と区切り

PowerBuilder ってのは癖の多い言語です。

しっかしですよね、コンパイラまで癖っていうか多い。

ちょっと頭きましたよ。かっときても仕様がないんですが

// THIS.X=PARENT.Width-THIS.Width-100
THIS.X = PARENT.Width - THIS.Width - 100

上のがダメなやつで、エラーを出してきます。

パーサーがなってないんですよ。

気をつけましょう。

木曜日, 4月 21, 2016

Arduino: ドットマトリクス・ディスプレイで遊ぶ


 ドットマトリクス・ディスプレイというものがあります。

ドット(点、それぞれLED)で構成されたディスプレイなわけですが、一行ずつ行のLEDを点灯すると、行ごとパターンが光ります。

これを繰り返していくとディスプレイ全体で図形が表示されるというのが一般的なドットマトリクス・ディスプレイの使い方です。

Arduino 単体でも 8x8 であれば動くわけですが、そのままだと行+列ぶんだけ信号線が要ります。この処理を引き受けてくれるICを使うとドットマトリクス・ディスプレイを楽しく使うことができます。



写真は MAX7219 を使ったキットです。よくできてます。作るときのワクワク感、できたときの満足感が保証できるのがキットのいいところといえるでしょう。出来上がりも見事です。明るく輝くLEDディスプレイで遊んでみました。

まずはキットから。MAX7219, セラミック、電解コンデンサ、抵抗とピンソケットをはんだ付けします。

そして、配線。

VCC    5V
GND    GND
DIN    8 ピン
CS    9 ピン
CLK    10ピン

こちら Arduino 用のスケッチです。ドットのパターンは Java アプリを書いて作成しました。

できた動画がこれです。今の気分を表してます (^^




このディスプレイを赤外線センサーPIRを使って手を振ると動作を開始するよう改良してみました。

リモートでも動くよう割り込みを調整してみました。

ブレッドボード Arduino で組めばそこかしこ置いて遊べます。

百均ケースでうまく収まってます。



#3Dプリンタで作るケースならしっかり収まります。STL ファイルはこちら(2017-12-23)





コードはこちらです。

#include <IRremote.h>
int pinCLK = 10;
int pinCS = 9;
int pinDIN = 8;
boolean displayOn = false;
int pir = 2;
int remote = 3;
IRrecv irrecv(remote);
decode_results results;
unsigned char dat[8] = {0b010000001,
0b001011010,
0b000100100,
0b001011010,
0b001011010,
0b000100100,
0b001011010,
0b010000001
};
unsigned char heart[8] = {0b00000000,
0b01100110,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100,
0b00011000
};
unsigned char smily[8] = {0b00000000,
0b01000010,
0b11100111,
0b01000010,
0b00000000,
0b01000010,
0b00100100,
0b00011000
};
unsigned char handsup[8] = {0b10000001,
0b01011010,
0b00100100,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00100100
};
unsigned char handshoriz[8] = {0b00000000,
0b00011000,
0b11100111,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00100100
};
unsigned char handsdown[8] = {0b00000000,
0b00011000,
0b00100100,
0b01011010,
0b10011001,
0b00011000,
0b00011000,
0b00100100
};
void WriteByte(unsigned char DATA)
{
unsigned char i;
digitalWrite(pinCS, LOW);
for (i = 8; i >= 1; i--)
{
digitalWrite(pinCLK, LOW);
digitalWrite(pinDIN, DATA & 0x80);
DATA = DATA << 1;
digitalWrite(pinCLK, HIGH);
}
}
void writeChar(unsigned char address, unsigned char dat)
{
digitalWrite(pinCS, LOW);
WriteByte(address);
WriteByte(dat);
digitalWrite(pinCS, HIGH);
}
void clearScreen()
{
for (int i = 1; i < 9; i++)
writeChar(i, 0);
}
void initDisplay(void)
{
writeChar(0x09, 0x00);
writeChar(0x0a, 0x03);
writeChar(0x0b, 0x07);
writeChar(0x0c, 0x01);
writeChar(0x0f, 0x00);
}
void setup()
{
pinMode(pir, INPUT_PULLUP);
pinMode(remote, INPUT_PULLUP);
pinMode(pinCLK, OUTPUT);
pinMode(pinCS, OUTPUT);
pinMode(pinDIN, OUTPUT);
delay(50);
initDisplay();
displayOn = true;
irrecv.enableIRIn();
attachInterrupt(digitalPinToInterrupt(pir), displayToggle, CHANGE);
attachInterrupt(digitalPinToInterrupt(remote), checkRemote, CHANGE);
}
void checkRemote()
{
if (irrecv.decode(&results)) {
displayOn = !displayOn;
irrecv.resume();
}
}
void displayToggle()
{
displayOn = !displayOn;
}
void loop()
{
if (displayOn)
{
for (int j = 0; j < 5; j++)
{
for (int i = 1; i < 9; i++)
writeChar(i, handsup[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handshoriz[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handsdown[i - 1]);
delay(100);
for (int i = 1; i < 9; i++)
writeChar(i, handshoriz[i - 1]);
delay(100);
}
for (int i = 1; i < 9; i++)
writeChar(i, smily[i - 1]);
delay(1000);
for (int i = 1; i < 9; i++)
writeChar(i, heart[i - 1]);
delay(1000);
displayOn = false;
clearScreen();
}
}

水曜日, 4月 13, 2016

PowerBuilder: タブページからタブそのものを切り替える

癖の多い PowerBuilder ですが、要は OOP ってことで、順序を踏めばきちんと動きます。

タブページのボタンからタブそのものを切り替えるなというときは、親タブのイベントを用います。

SelectTab() という関数は、タブ名をインデックスあるいは文字列で指定できます。

タブページは Control 配列で指定できます。

tab ltb_tab
u_onboarding_monitor luo_monitor

ltb_tab=PARENT.GetParent()
ltb_tab.DYNAMIC SelectTab('tabpage_onboarding_monitor') 

luo_monitor=ltb_tab.Control[ltb_tab.selectedtab]
luo_monitor.EVENT ue_Search()

月曜日, 4月 11, 2016

Arduino: 有機ELディスプレイを使う

今日、有機ELディスプレイが届きました。有機ELは英語で OLED ですね。有機ELは液晶ディスプレイよりまだ高価ですが、近い将来、市場を席巻するだろうという未来の素材です。


有機ELは発光素子を挟み込んだ画面を用います。発光素子を直接光らせるので、画面のバックライトをフィルターして見せている液晶より明るく、消費電力が少ないわけです。バックライトが必要ないため薄くできます。


薄くて明るく消費電力の少ないという有機ELですが、そろそろ手ごろな値段で出ています。さっそく注文してみました。この価格帯だと解像度というレベルのものではないですが、細かい文字も表示できます。


この小さなディスプレイは、端子はたったの4つ。



ライブラリなどは128x64サイズのものを使えばそのまま文字でもビットマップでも表示できます。

https://github.com/adafruit/Adafruit_SSD1306
https://github.com/adafruit/Adafruit-GFX-Library

このライブラリですが、使用の際ディスプレイのアドレスを得る必要があります。

http://playground.arduino.cc/Main/I2cScanner

アドレスを得たら初期化のとき引数として渡してやります。

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 

この画面サイズの場合、ヘッダファイル(Adafruit_SSD1306.h)を書き換える必要があります。

   #define SSD1306_128_64
//   #define SSD1306_128_32
//   #define SSD1306_96_16


ライブラリを使っての HelloWorld! スクリプトです。

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
Serial.begin(9600);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
/*
for (uint8_t i=0; i < 168; i++) {
if (i == '\n') continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
*/
/*
String str="Hello World!";
for(uint8_t j=0;j<5;j++)
{
display.setTextSize(j);
// for(uint8_t i=0;i<str.length();i++)
for(uint8_t i=0;i<1;i++)
{
// display.write(str.charAt(i));
display.write('A');
}
// display.println();
}
*/
String str="Hello World!";
display.setTextSize(1);
display.println(str);
display.display();
display.startscrollright(0x00, 0x0F);
delay(1000);
display.stopscroll();
delay(500);
display.startscrollleft(0x00, 0x0F);
delay(1000);
display.stopscroll();
delay(500);
display.startscrolldiagright(0x00, 0x0F);
delay(1000);
display.startscrolldiagleft(0x00, 0x07);
delay(1000);
display.startscrolldiagright(0x00, 0x0F);
delay(1100);
display.startscrolldiagleft(0x00, 0x07);
delay(850);
display.stopscroll();
}
void loop() {
}
view raw helloOLED.ino hosted with ❤ by GitHub


動きました!ので、使いやすいよう Arduino 用有機ELディスプレイ・モジュールを作ってみました。

ここで晒すのもなんですが、配線はこんな感じです。アナログ入力端子をふさがないよう長足のピンソケットをつけています。モジュールだと配線を考えなくていいので使いやすいです。


モジュールが使いやすいってのはつまり配線を間違えることがない、成功率が高い、能率がいい、ひいては使う際の敷居が低いってことでもあります。すべからくモジュールを組んでおくと Arduino の良さを満喫できます。

#使ってみると有機ELディスプレイってのはいいです。小さいし軽い。電池も持つしいうことないです。早くもっと普及してほしい。

#この「IICシールド」、他のIIC機器用のシールドとしても使えます。時計モジュールとつなぐとそのまま時刻が読めます。


月曜日, 3月 28, 2016

PowerBuilder: ドロップダウン・リストの長さを指定する

米国も選挙の季節です。反日の方々の声が大きくなるので困りものです。うけるんですよねそういうの

ソニーを敵視するとかありますね。女性へいやらしいセリフを繰り返す男性が「日本」だとか…ばかみたいですよねほんと

しかしですね、米国のすべてのネガティブな部分が日本のせいだとかそういうことはないです。自動車産業とか鉄鋼とか(票田である)産業が落ち目なのは働き者のアジアが勝利したからです。断言

ソフト産業は米国が強いですけどね。そしてIT業界は米国民主党よりです。ハイ

閑話休題。


PowerBuilder でドロップダウンリストを作る方法、というよりドロップダウンリストの長さを指定する方法を編み出したので紹介します。

PowerBuilder ではデータウインドウでドロップダウンリストを作り、データベースの値を指定することができます。

これは正規の方法で指定できます。ドロップダウンデータウィンドウを指定すればデータベースの値でドロップダウンリストを作ることができます。

この方法でドロップダウンリストを指定すると、長さは指定できません。空白行ができます。

この空白行を削除するためのスクリプトの話です。

String ls_count
ls_count=String(ldwc_dddw.RowCount())
dw_corp_onboarding_config.GetChild("survey_integration_app_id", ldwc_dddw)
dw_corp_onboarding_config.Modify("survey_integration_app_id.dddw.Lines="+ls_count)
view raw drop-down-list hosted with ❤ by GitHub
IDEではこの属性を指定できないのでスクリプトを書く必要があります。

まあ、要素を取り出して属性を指定するだけですが…

癖の多い PowerBuilder ですが、スクリプトが書けるだけ自由度もあるわけです。

分かるだけ書けるだけ書いていきたいと思います。

木曜日, 3月 10, 2016

PowerBuilder: グリッド・データウインドウ・コラムのソート

PowerBuilder はデータベースと親和性の高い言語です。

データベースのデータを表で表すなどという操作を得意とします。

SQLをデータウインドウで指定するとそのまま表示してくれます。

プログラムでSQLを直接記述できるのも PowerBuilder ならではの良さと言えるでしょう。こんな感じです。これでテーブルの指定したコラムの値を得ることができます。
SELECT コラム名
INTO :変数名
FROM テーブル名
WHERE 条件
USING SQLCA;

独特の癖の多い PowerBuilder ですが、このDB親和性という点ではオススメできる言語です。

しかしですね、この「癖」なんですが改善すべきと思われるところもあります。

グリッドのコラムをソートする状況があって、でここではまりました。

他のコラムはそのまま表の見出しをクリックするとソートしてくれるわけなんですが、ソートしてくれないコラムがある。

フラグでも指定しているのかとソースを追ったわけですが…

なんとなんとここは「ヘッダーの変数名」ってのがネックだったわけですね。

ヘッダーの変数名は _t で終わっていないとならない。なんだそりゃ

つまらないオチですが…

ヘッダーの変数名は_t と指定する必要があります。それだけです
  
命名規約というのは重要とはいえ、これは紳士規約ですよ。

そんなものを規定して動作を指定するなどルール違反です。

この裏切られた感ってのが強烈な PowerBuilder でした。

土曜日, 2月 20, 2016

Arudino: オペアンプを使ってマイクを作る

コンデンサマイク
極性があります


コンデンサマイクがようやく届きました。モジュールではないのでそのままでは信号が弱いので使えません。信号を増幅する必要があります。

ちょっとした手間ですが、首尾よく動いてくれました。この回路の応用で、使えるマイクが出来ます。



増幅回路ですが、ここではオペアンプを使ってみました。仕組みはともかく、オペアンプってのは便利です。使ってみると実感があります。つなぐ抵抗値で信号の増幅できます。

電源とGNDをつなぎ、ー(マイナス)入力ピンとマイクを抵抗を介してつなぎ、出力ピンと抵抗をつなぎます。この抵抗の比が増幅率となります。入力が交流であるため、抵抗で+(プラス)入力ピンの電圧を調整します。

マイクと電源をつなぎ、入力をコンデンサを介してつなぐとこれで回路が完成します。



Arduino のアナログ入力ピンとつなぎ、電源とGNDを供給してやると音声を電気信号として読み取ることができます。


これだけ増幅できるなら、ということでPCのマイク端子とつないでみました。と、マイクとして使えます。Skype が動きます。


Arduino で電気回路として実現、しかも実用として使えるというこの流れ。知識が実用となったという実感。大きく広がる世界と可能性。

Arduino っていいなあと思った次第でした。

以下、部品リストです。

C1    Capacitor
MIC1    Microphone
Part1    Arduino Uno (Rev3)
R1    100kΩ Resistor
R2    100kΩ Resistor
R3    1kΩ Resistor
R4    100kΩ Resistor
R5    10kΩ Resistor
U1    LM358

#補足です。ノイズがのるので電源を USB から供給してはなりません。

火曜日, 2月 09, 2016

PowerBuilder 12.6: 日付をフォーマットする

PowerBuilder では Time, Date, DateTime などという型があります。

デフォルトの表示形式から変更する場合は String() 関数を使います。

String(Date('1/12/2016'),'yyyy-mm-dd')

SQLなどで表記を変更したい時など便利です。

火曜日, 1月 19, 2016

Arduino: ステッピングモーター


 モーターの種類はいろいろとありますが、回転の位置を指定できるサーボモータが一般的です。

ここではあえて価格の手ごろなステッピングモーターを使ってみました。

ドライバ回路はトランジスタで組んでみました。

モータの配線がやっかいで、順番を間違えると振動するだけで回転しません。

#include <Stepper.h>
const int stepsPerRevolution = 32*64;
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
void setup() {
myStepper.setSpeed(10);
}
void loop() {
myStepper.step(stepsPerRevolution);
delay(500);
myStepper.step(-stepsPerRevolution);
delay(500);
}

日曜日, 1月 17, 2016

Arduino: リレー回路を組む


今週リレーが届きました。Arduino ではリレー単体で動かすことはできないので、トランジスタを使って回路を組む必要があります。週末まで放置してあったわけですが今日組んでみました。


モジュールもいいですが、リレー単体だと安くまとめ買いできます。トランジスタひとつで動くわけなので、やる気があればモジュールでなくても動きます。逆流防止のためのダイオードと抵抗を使います。

作ったモジュールはこれ。




作ってみて便利だと思ったのはこのデュポン・ジャンパー線。短く切って端子をカシメると便利です。


クリップをつけることもできます。


あと、部品の足がブレッドボードのピッチと合わない場合があります。こんなときはユニバーサル基板を切ってピンヘッドをつけるといいです。しっかり固定することができます。

Qt: 外部プログラムを起動する

  Qt/C++ のアプリは、外部へ直接アクセスできます。これはネットアプリでは不可能な Qt のメリットです。 外部プログラムを起動することもできます。QProcess::startDetached() を使うと独立したプロセスを立ち上げることができます。 この QProces...