2011年9月30日金曜日

SFっぽい「先進個人装備システム」

「防衛省のガンダム」とまで言われた先進個人装備システム
本家は+α的な感じだけど
SFっぽいタイプを妄想してみる

1. 照準には赤外/可視光のカメラを使用
2. HMDで照準やその他情報を表示
3. 高速無線通信により個人が装備している銃やアイカメラの映像を司令部等に送信
4. 高精度位置測定システム等を併用し最適な位置配置を実現

って感じの
実際にはもっと複雑でいろいろな機能がある
例えばレーザーは照準だけじゃなくて距離測定に使ったりとか

大型の兵器を相手にするのには不向きだけど
敵基地の破壊工作とかには最適
もちろん対テロの市街地戦とかにも有用

まぁここまでのは本家でも似たようなことができるけど

更に上を行って
例えば的地上施設の攻撃なら
まず4人程度のチームで偵察して
送られた位置にGPS誘導の艦砲なり航空機のレールガンで攻撃するなり
とか

まぁそんなテクノロジーあってなんで戦争してんだよって話だけどねぇ
そこはあくまで「SFですから」と

シューティングゲームとか 作ってみたいよなぁ
MGSとかCoDのクオリティでは無理だけどさ

2011年9月21日水曜日

しかしまぁ


char cBit = 0;
for (int i = (buSize - 1); i >= 0; i--) {
Answer[i] = (Num1[i] + Num2[i]) + cBit;
if (Answer[i] > 9) {
Answer[i] -= 10;
cBit = 1;
} else { cBit = 0; }

Answer[i] += '0';
}

たとえ1000桁以上同士の足し算とか言っても
配列で1500要素を5セット(7500byte)+αを確保するとかなると
組み込みやってる身としては反逆にも近いよね

このコードは眠気覚ましに作った奴だから
誤入力対策とかもしてないし
いろいろ無駄な処理してるけど

AOJの80桁の足し算だけなら85byte使うかどうかくらいかな
やりたかねぇけど…
PICでも80桁同士の足し算ならできるね
と言うか引き算くらいなら出来るんじゃないかな


あと 森川空のルールいいよね
あいはらまひろさんの長編とかも好き

とりあえずまぁ

学食でわかめごはんS頼んだのになぜかMが出てきて
そのまま食ったけど寝不足で例のごとく吐き気が出るほどに眠くて
眠気覚ましにとか言って1000桁同士の足し算とかを
実装しちゃうくらいにはCに慣れてきた
まぁROM/RAM/時間制限無しだけどねw
一応2000桁同士でも大丈夫なはずなんだけどMacの文字入力制限があるっぽい

あっ 一応無事帰宅しました^^
(帰ったら即寝そうだから車の中でかいてるのはヒミツ)

AOJのアカウントなんてとっくに忘れてるし(蹴
まーそのまま通るわけもないから
誰か暇な人試してみてよーとか思いつつ

あと引き算実装すれば
掛け算とわり算が作れないこともないから
いろいろ遊べる と思う

あー 液晶モジュール…

そういえば

\祝:Google Chrome Mac OS X 10.7 Lion 完全対応/
フルスクリーンもできるし二本指で戻れるし
これでMacBookでもGoogle Chromeが使いやすく!
なったはずなんだけど…
うーん やっぱSafari使っちゃうなぁ
なんでだろう
デスクトップだとGoogle Chrome神ってるんだけどなぁ
Safariに慣れちゃったから?
でも
「iMacにWin入れてその上で走らせたGoogle Chromeの速度」
はすごいよね PVがw
確かiMacだったはずですけども

グーグル日本語入力も進化してることですし
デスクトップの場合しばらくはGoogle製品で固めちゃうのもアリかも
Google Chrome+グーグル日本語入力+Picasa
でだいたいのことはできちゃう
SketchUpは使いやすいし Google Earthも回線早けりゃ面白いよね
office系も互換性気にしなけりゃ問題ないしw

PCの進化はまだまだ続きそうです!
みたいな

2011年9月20日火曜日

LCDモジュールに外字登録

とりあえず動作版
コードだけ

void LCD_cset(char addr, char data[]) {
addr = addr << 3;
LCD_8set(0x40 + addr + 0, 0);
LCD_8set(data[0], 1);
LCD_8set(0x40 + addr + 1, 0);
LCD_8set(data[1], 1);
LCD_8set(0x40 + addr + 2, 0);
LCD_8set(data[2], 1);
LCD_8set(0x40 + addr + 3, 0);
LCD_8set(data[3], 1);
LCD_8set(0x40 + addr + 4, 0);
LCD_8set(data[4], 1);
LCD_8set(0x40 + addr + 5, 0);
LCD_8set(data[5], 1);
LCD_8set(0x40 + addr + 6, 0);
LCD_8set(data[6], 1);
LCD_8set(0x40 + addr + 7, 0);
LCD_8set(data[7], 1);
}
これだと一応そこそこには動く
時々変なんだよなぁ…

詳しい人いたら教えて下さい><

ぼくは…寝ますorz
5時起きだしね それが4日間程度
無事日曜を迎えられる自信がないよ…

まぁとりあえず動いてるようなんでこのまま使って
時間が開いたときに動作確認真面目にやります

LCD_8setは引数1個目が送信するデータ
引数2個目がRSです


液晶を初期化してからすぐデータを送ると変なゴミが残ってる
初期化後に一旦クリア(0x01, 0)を送信すると問題ない

「こういうモン」なの?

【追記】LCDモジュールに外字登録

追記
 このコードとんでもないバグを抱えてるらしい
 壊れはしないと思うけど なんか怪しい
 ということで↓のコードは使用禁止
 できれば今日中に修正コード書きます
 が 明日朝早いので無理だったら来週まで更新できませんorz
 (水曜日~土曜の4日連続で早朝出発のイベントが...)
******************************************************

マイコンで制御できる液晶モジュール(*)に外字登録を試してみたよ

今回作った関数はこれ↓
/* *** */

void LCD_Cset(char addr, char ca[]) {
LCD_8set(0x40 + addr, 0);
putch(ca[0]);
putch(ca[1]);
putch(ca[2]);
putch(ca[3]);
putch(ca[4]);
putch(ca[5]);
putch(ca[6]);
putch(ca[7]);

LCD_clear();
}

/* *** */
使い方は
/* *** */

const char data[] = {
0b00000000,
0b00000100,
0b00000100,
0b00011111,
0b00000100,
0b00000100,
0b00011111,
0b00000000 };
LCD_Cset(0, data);

/* *** */
みたいな感じで
でも配列を使うと結構コストが高いから
配列を使わないようにしてもいいかも

putchはHI-TECHでprintf関数を使えるようにするためのもの
簡単に言うとRSを1にして1byte送信

表示する場合はaddrで指定したアドレスをRSを1にして送信すればいいです

外字登録って結構便利で
ゲームを作ってる人とかカレンダーを作ってる人もいるみたい
あとおっきな文字を表示することもできるらしい

注意点としては外字は8文字までしか登録できないみたい
8文字を超えて登録しようとした時の処理とかは書いてないから各自注意してください


ということで 覚えておくとちょっと便利な小ネタでした

*これとかこれで動作確認をしたよ

2011年9月19日月曜日

アペンドさんが遊びに来たよ!

うーん 首がアレなのは撮ってみないとわからなかったな…


左はDIVAのおまけだっけ?
Android君が踏まれてます…
Android<我々の業界ではご褒美です!


青色LEDとかで照らしてもいいかも
今回は琥珀色なので
と言うかフルカラーの5mmが何個か有ったはず
あれハーフピッチだから使いにくいのよ…


LAT式もいいなぁと思ったんだけど
あぺんどは結構LEDで遊べそうだったので
なんというかなんかアレな理由ですけどね
あと関節がすごい
中国すげぇ

これ1/8だったかな
1/1だと不気味の谷現象とかあるんだろうなぁと思うと1/3くらいが限界なのか?
コスト的にも

でもロボット好きとしては不気味の谷現象を早く突破して欲しいですね
とりあえず人工筋肉のトルクを上げるところからスタートですね^^

Parallels Desktop 7 Mac版

Parallels Desktop 7 Mac版を試してみたよ
今回は体験版だけど


とりあえずエクスペリエンスインデックスを試してみた

↓ これがBoot Campで試した時のログ


↓ そしてこれがParallels Desktopで試したもの

全体的に落ちてるけど ハードディスクのポイントが若干上がってる
これくらいなら偶然ってこともあり得るけど

ちなみに↓がデスクトップマシンで試したもの

スペック
MacBookPro
Thunderbolt初搭載モデル/カスタム無し
CPU: Core i5 2415M @ 2.3GHz
RAM:4GB(Parallelsでは1G割り当て)
  OS:Win7Ux64

デスクトップマシン
CPU:Core 2 Quad 8400 @ 2.66GHz
RAM:8GB
  OS:Win7Ux64

CPUはMacBookProのほうが性能いいはずなんだけどなぁ…
0.36GHzの違いが出たか?
RAMはさすがに実装量が違う

グラフィックは
デスクトップがグラボ(GeForceGT220)に対して
MacはCPUのグラフィック機能を使ってる
実機同士だとスコアが0.1ポイント違う程度だから
CPUの進化はすごいということらしい

HDDのスコアが同じ程度というのは
Appleのこだわりか?
デスクトップは中古の安いヤツを買ってきてつけてるだけだし…


とりあえず2Dのノベルゲーム程度なら仮想でも十分
さすがにトラックパッドでMetasequoiaは至難の業だから気にしないことにする
ArduinoとかmbedもMacで開発できるから気にしない
手持ちのPICKit3は一応書き込みできるっぽいです 書き込みしか試してないですが
そしてNetduinoも ちゃんと動作するみたいです


一応趣味で組み込みみたいなことやる分には問題ないみたい
ただノートならバッテリーの問題があって
Mac+WinのOSの分電池を大量に使うから
屋外で使うならBoot Campで起動したほうがいいと思う
動作も全体的にもっさりしてる感じは否めないしね

でも電源が有るところで使うなら有用かも
ちょっと値段が高いのが難点だけどね


ただぼくはこの値段を払ってまで使う用途を見いだせなかったから
しばらくは買わないかな

2011年9月17日土曜日

フラップ


胴体と干渉してるけど
フラップの実験
結構いい感じ

あーぁ… 主翼作り直し?

後部ハッチをもっと開くように出来ればガンシップにしても面白いかも
高高度からレールガンを発射できるようにして
3km/sくらいで12発/分程度の能力があれば
面白いかも
メガトロンが攻めてきても安心w


2011年9月16日金曜日

とりあえず

残り

  1. 脚類
  2. 尾翼
  3. 各部フィレット
  4. エンジン
という感じのところまできた
画像は空中給油キットを装備した状態で前部及び後部ハッチを開いた状態
左が前
前部ハッチから若干タンクが見えてる
給油キットはフェリー時に使うこともできる
ただ積めるだけ燃料積んじゃうと最大着陸重量超えるんじゃないかと思う
…大丈夫か...

とりあえず機体だけを表示するとツチノコっぽいんだよねw


結局

こんな形になった
まぁネタとして
こういうのもアリなんじゃないかなと

エンジンは6基
カラで200tとして
貨物120tを積めるとする むちゃくちゃだな

とりあえず320t
10%として6基だから
エンジン1基あたり6t程度あれば最低限飛べることは飛べる

けどまぁもうちょっと余裕がほしいね 
1基10tあればそこそこ性能出るか

レールガンとか積んでも面白そう

2011年9月15日木曜日

DIPスイッチを使うよ

今回はDIPスイッチの基本的な使い方を解説するよ



回路は↓これ
どっか間違ってる気もするので参考程度に
DIPSWの左側がプルアップ抵抗 今回は470Ωを使ったけど本来はV+に直結するべき
DIPSWの右側はプルダウン抵抗 4.7kΩを使ったよ
基本的にこれだけで使える
スイッチがOFFだとPICはLになりスイッチがONだとPICはHになる
一般的にはプルアップしてスイッチを押すとLになるけど
今回はわかりやすいように(+後々簡単なように)アクティブHにした

そしてコードは↓これ
/* *** */

#include <htc.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & BOREN_OFF & LVP_OFF & DEBUG_OFF);

#define _XTAL_FREQ 20000000
#define TXP RC6

void send(char);

void main(void) {
TRISC = 0x0F;
PORTC = 0;
TXP = 1;

char data = 0;

while(1) {
if (data != (PORTC & 0x0F)) {
send(0x08);
data = (PORTC & 0x0F);
send(data + (data > 9 ? (0x37) : ('0')));
}
__delay_ms(5);
}
}

void send(char ca) {
TXP = 0; __delay_us(100);
TXP = ((ca >> 0) & 1); __delay_us(100);
TXP = ((ca >> 1) & 1); __delay_us(100);
TXP = ((ca >> 2) & 1); __delay_us(100);
TXP = ((ca >> 3) & 1); __delay_us(100);
TXP = ((ca >> 4) & 1); __delay_us(100);
TXP = ((ca >> 5) & 1); __delay_us(100);
TXP = ((ca >> 6) & 1); __delay_us(100);
TXP = ((ca >> 7) & 1); __delay_us(100);
TXP = 1; __delay_us(100);
}
/* *** */

一応
5ms毎にスイッチを監視し変更があればASCII16進に変換してバックスペースと共に送信
という感じ
これはぼくが作ったLCDモジュールの仕様によるもので
バックスペース(0x08)→1行目1文字目に移動
ENTER(0x13)→2行目1文字目に移動
ESC(0x1B)→表示クリア
になってるから


今回はこれ以外に機能を付けなかったから通常のポート使用量だけど
気が向いたらもうちょっと少ないポート数で使えるような工夫も紹介するかも

2011年9月9日金曜日

PICでLチカ【改】

#include <htc.h>
#include <config.h>

#define _XTAL_FREQ 20000000

#define LED RB5

void main(void) {
TRISA =   0b000000;
TRISB = 0b00000000;
TRISC = 0b00000000;
PORTA = 0;
PORTB = 0;
PORTC = 0;

while(1) {
LED = !LED;
__delay_s(1);
}
}

コンフィグをヘッダにすることで移植を楽にした

自分は現状88と873Aしか使ってないから

#if defined(PIC16F88)
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & LVP_OFF & DEBUG_OFF);
#endif

#if defined(PIC16F873A)
__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & BOREN_OFF & LVP_OFF & DEBUG_OFF);
#endif
みたいな感じになってる

これでプロジェクトを作るときに選択した石のコンフィグが作られる
まぁ「典型的なコンフィグ」しか設定できないけどね
ちょっと動作確認したいだけならこれでも大丈夫だと思う

Netduinoでモールス符号

/* *** */

using System.Threading;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusApplication1
{
    public class Program
    {
        public static OutputPort LED;

        public static void Main()
        {
            LED = new OutputPort(Pins.ONBOARD_LED, false);

            int waittime = 100;

            while (true)
            {
                sendText("SOS", waittime);
            }
        }

        public static void sendText(string text, int sigtime)
        {
            for (int i = 0; i < text.Length; i++)
            {
                sendMorse(getMorse(text[i]), sigtime);
            }
            Thread.Sleep(sigtime * 7);
        }

        public static void sendMorse(string morse, int sigtime)
        {
            if (morse[0] != '0')
            {
                for (int i = 0; i < morse.Length; i++)
                {
                    LED.Write(true);
                    Thread.Sleep((morse[i] == '1' ? (sigtime) : (sigtime * 3)));
                    LED.Write(false);
                    Thread.Sleep(sigtime);
                }
            }
            Thread.Sleep(sigtime * 3);
        }

        public static string getMorse(char c)
        {
            switch (c)
            {
                case ('A'): return "12";
                case ('B'): return "2111";
                case ('C'): return "2121";
                case ('D'): return "211";
                case ('E'): return "1";
                case ('F'): return "1121";
                case ('G'): return "221";
                case ('H'): return "1111";
                case ('I'): return "11";
                case ('J'): return "1222";
                case ('K'): return "212";
                case ('L'): return "1211";
                case ('M'): return "22";
                case ('N'): return "21";
                case ('O'): return "222";
                case ('P'): return "1221";
                case ('Q'): return "2212";
                case ('R'): return "121";
                case ('S'): return "111";
                case ('T'): return "2";
                case ('U'): return "112";
                case ('V'): return "1112";
                case ('W'): return "122";
                case ('X'): return "2112";
                case ('Y'): return "2122";
                case ('Z'): return "2211";

                case ('1'): return "12222";
                case ('2'): return "11222";
                case ('3'): return "11122";
                case ('4'): return "11112";
                case ('5'): return "11111";
                case ('6'): return "21111";
                case ('7'): return "22111";
                case ('8'): return "22211";
                case ('9'): return "22221";
                case ('0'): return "22222";

                default: return "0";
            }
        }
    }
}
/* *** */
とりあえずアルファベットと数字だけ

しかしまぁ最近回線速度が酷く遅い
測定サイトだと下り5上り1位出てるから
遅いって言うほど遅くもないんだけど
なぜかページが開けない
どうやらアップリンクが捨てられてる時が有るらしいんだが
ウイルス対策ソフト?

2011年9月5日月曜日

PICで液晶

/* *** */

#include <htc.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & BOREN_OFF & LVP_OFF & DEBUG_OFF);

#define _XTAL_FREQ 20000000

#define E RB0
#define RS RB1
#define RW RB2

#define D4 RA3
#define D5 RA2
#define D6 RA1
#define D7 RA0

void LCD_init(void);
void LCD_clear(void);
char LCD_printf(char text[]);
void LCD_8set(unsigned char, char, char);
void LCD_4set(unsigned char, char, char);

static void interrupt intr(void) {
if (RCIF) {
RCIF = 0;
char c = RCREG;
if (c == 0x1B) { LCD_clear(); return; }
if (c == 0x08) { LCD_8set(0x80, 0, 0); return; }
if (c == 0x0D) { LCD_8set(0xC0, 0, 0); return; }
LCD_8set(c, 1, 0);
}
}

void main(void) {
TRISA = 0b000000;
TRISB = 0b00000000;
ANSEL = 0;
PORTA = 0;
PORTB = 0;

LCD_init();

LCD_printf("LCD init ok...");
__delay_s(1);
LCD_clear();

for(;;) {
LCD_printf("hello");
__delay_s(1);
LCD_clear();
__delay_ms(1);

LCD_printf("world");
__delay_s(1);
LCD_clear();
__delay_ms(1);
}
}

void LCD_init(void) {
__delay_ms(15);

LCD_4set(0x30, 0, 0);
__delay_ms(5);
LCD_4set(0x30, 0, 0);
__delay_ms(1);
LCD_4set(0x30, 0, 0);

LCD_4set(0x20, 0, 0);

LCD_4set(0x20, 0, 0);
LCD_4set(0x80, 0, 0);

LCD_4set(0x00, 0, 0);
LCD_4set(0x80, 0, 0);

LCD_4set(0x00, 0, 0);
LCD_4set(0x01, 0, 0);

__delay_ms(2);

LCD_8set(0x06, 0, 0);

LCD_8set(0x80, 0, 0);

LCD_8set(0x0C, 0, 0);
}

void LCD_clear(void) {
LCD_8set(0x01, 0, 0);
__delay_ms(1);
LCD_8set(0x0C, 0, 0);
}

char LCD_printf(char text[]) {
char c;
for (c = 0; text[c] != '\0';c++)
{ LCD_8set(text[c], 1, 0); }
return c;
}

void LCD_8set(unsigned char data, char RSb, char RWb) {
LCD_4set(((data << 0) & 0xF0), RSb, RWb);
LCD_4set(((data << 4) & 0xF0), RSb, RWb);
}

void LCD_4set(unsigned char data, char RSb, char RWb) {
RS = RSb;
RW = RWb;
D4 = ((data >> 4) & 1);
D5 = ((data >> 5) & 1);
D6 = ((data >> 6) & 1);
D7 = ((data >> 7) & 1);

__delay_us(500);
E = 1;
__delay_us(1000);
E = 0;
}
/* *** */

PIC16F88 @ 20MHz
液晶との接続はコード最初のほうで確認してください
あと__delay_s()の追加をしてない人は
__delay_msに修正するなり
#define __delay_s(sec) { __delay_ms(sec * 1000); }
とか書き足すなり(動作確認はしてないけど)
適当に対応してください


実はこれARMチャレンジャーの液晶の動作確認に作ったコード
なぜかARMからだと動作してくれなかったので
PICで動作確認
んでこのコードをARMに移植しても動かないんだよね…
LCDの電源が5VでARMが3.3Vだからとかいうくだらない理由でも無いと思うんだけど…
何なんだろう

2011年9月4日日曜日

手っ取り早くPICでデバッグするためのUSART

/* *** */

void send(unsigned char data) {
TXP = 0;
__delay_us(100);
TXP = ((data >> 0) & 1);
__delay_us(100);
TXP = ((data >> 1) & 1);
__delay_us(100);
TXP = ((data >> 2) & 1);
__delay_us(100);
TXP = ((data >> 3) & 1);
__delay_us(100);
TXP = ((data >> 4) & 1);
__delay_us(100);
TXP = ((data >> 5) & 1);
__delay_us(100);
TXP = ((data >> 6) & 1);
__delay_us(100);
TXP = ((data >> 7) & 1);
__delay_us(100);
TXP = 1;
}

/* *** */

出力するポートを予め
#define TXP RA4
みたいに定義しておく必要があります
あと__delay_usを使うためにhtc.hもインクルードする必要があります
それと↓みたいにコンパイラに動作クロックを指定する必要があります
#define _XTAL_FREQ 20000000 // 動作クロック20MHz

ということで内部クロックを使って動作周波数が可変とかだと無理です
そういう時はdelay関数自分で作ってください


とりあえずこれだけで9600bpsで一文字送信はできます