前提・実現したいこと
マイコンのATmega1284Pを用いて様々なセンサーを使い得たデータをバイナリデータとして送信したいです。
発生している問題・エラーメッセージ
setup()関数の処理が終了したことを示す"Start"が出力された後、loop()関数で出力されるはずのバイナリデータが出力されずにまたsetup()関数に戻り“Start”が出力され、それが繰り返されています。たまにloop関数が作動してバイナリデータがシリアルモニタに出力されることもありますが、4,5回でまたsetup()関数に戻り“Start”が出力されます。
ATmega1284PはArduinoIDEでブートローダーを書き込み、arduino互換機として動作させています。
該当のソースコード
arduino
1#include <Wire.h> 2#include <MadgwickAHRS.h> 3#include <math.h> 4#include <SoftwareSerial.h> 5 6//ピン番号 7int r_pin = A0; 8int e_pin = A1; 9int h_pin = 0; 10int cad_pin = 1; 11int A_pin = 2; 12 13//ソフトウェアシリアル(rx, tx) 14SoftwareSerial GPSSerial(18, 19); 15SoftwareSerial W0Serial(20, 21); 16SoftwareSerial MissileSerial(22, 23); 17 18const byte HEAD_BYTE = 0x7E; 19const byte ESCAPE_BYTE = 0x7D; 20const byte ESCAPE_MASK = 0x20; 21float data[18]; 22byte buf[48] = {HEAD_BYTE, 0, 0, 0, 0, 0, 0, 0}; 23byte Sequence = 0; 24 25void setup() { 26 Serial.begin(115200); 27 Serial1.begin(19200); 28 pinMode(cad_pin,INPUT); 29 pinMode(r_pin,INPUT); 30 pinMode(e_pin,INPUT); 31 pinMode(h_pin,INPUT); 32 attachInterrupt(2, PulseCount, RISING); 33 34 GPS_Init(); 35 W0Serial.begin(9600); 36 MissileSerial.begin(9600); 37 38 Wire.begin(); 39 BMX055_Init(); 40 LPS25HB_Init(); 41 Serial.println("Start"); 42} 43 44void loop() { 45 dataAquisition(); 46 Recordbuf(data); 47 for(int i=0; i<48; i++){ 48 Serial.print(buf[i],HEX); 49 Serial.print(" "); 50 } 51 Serial.println(""); 52} 53 54//データ取得 55void dataAquisition() { 56 int rud = analogRead(r_pin); 57 int elv = analogRead(e_pin); 58 59 data[0] = rud; 60 data[1] = elv; 61 getrpm(); 62 getHeight(); 63 getAttitude(); 64 getGPS(); 65 getBaro(); 66 getASpeed(); 67 data[13] = -13.32; 68 data[14] = 1.26; 69 data[15] = -2.1; 70 data[16] = 1.23; 71 data[17] = 7.86; 72} 73 74//データ変換 75void Recordbuf(float d[]) { 76 Sequence++; 77 unsigned long integerData[18]; //小数点があると嫌 78 for (int i = 0; i < 18; i++) { 79 switch (i) { 80 case 0: 81 case 1: 82 integerData[i] = d[i]; 83 break; 84 85 case 2: 86 case 10: 87 integerData[i] = d[i] * 10; 88 break; 89 90 case 7: 91 case 8: 92 integerData[i] = d[i] * 10000000; 93 break; 94 95 default: 96 integerData[i] = d[i] * 100; 97 } 98 } 99 buf[1] = Sequence; 100 buf[8] = (integerData[0] >> 0) & 0xFF; 101 buf[9] = (integerData[0] >> 8) & 0xFF; 102 buf[10] = (integerData[1] >> 0) & 0xFF; 103 buf[11] = (integerData[1] >> 8) & 0xFF; 104 buf[12] = (integerData[2] >> 0) & 0xFF; 105 buf[13] = (integerData[2] >> 8) & 0xFF; 106 buf[14] = (integerData[3] >> 0) & 0xFF; 107 buf[15] = (integerData[3] >> 8) & 0xFF; 108 buf[16] = (integerData[4] >> 0) & 0xFF; 109 buf[17] = (integerData[4] >> 8) & 0xFF; 110 buf[18] = (integerData[5] >> 0) & 0xFF; 111 buf[19] = (integerData[5] >> 8) & 0xFF; 112 buf[20] = (integerData[6] >> 0) & 0xFF; 113 buf[21] = (integerData[6] >> 8) & 0xFF; 114 buf[22] = (integerData[7] >> 0) & 0xFF; 115 buf[23] = (integerData[7] >> 8) & 0xFF; 116 buf[24] = (integerData[7] >> 16) & 0xFF; 117 buf[25] = (integerData[7] >> 24) & 0xFF; 118 buf[26] = (integerData[8] >> 0) & 0xFF; 119 buf[27] = (integerData[8] >> 8) & 0xFF; 120 buf[28] = (integerData[8] >> 16) & 0xFF; 121 buf[29] = (integerData[8] >> 24) & 0xFF; 122 buf[30] = (integerData[9] >> 0) & 0xFF; 123 buf[31] = (integerData[9] >> 8) & 0xFF; 124 buf[32] = (integerData[10] >> 0) & 0xFF; 125 buf[33] = (integerData[10] >> 8) & 0xFF; 126 buf[34] = (integerData[11] >> 0) & 0xFF; 127 buf[35] = (integerData[11] >> 8) & 0xFF; 128 buf[36] = (integerData[12] >> 0) & 0xFF; 129 buf[37] = (integerData[12] >> 8) & 0xFF; 130 buf[38] = (integerData[13] >> 0) & 0xFF; 131 buf[39] = (integerData[13] >> 8) & 0xFF; 132 buf[40] = (integerData[14] >> 0) & 0xFF; 133 buf[41] = (integerData[14] >> 8) & 0xFF; 134 buf[42] = (integerData[15] >> 0) & 0xFF; 135 buf[43] = (integerData[15] >> 8) & 0xFF; 136 buf[44] = (integerData[16] >> 0) & 0xFF; 137 buf[45] = (integerData[16] >> 8) & 0xFF; 138 buf[46] = (integerData[17] >> 0) & 0xFF; 139 buf[47] = (integerData[17] >> 8) & 0xFF; 140}
Serial.printで送信している箇所(loop内のfor文以降)はデバッグのためにprintを使っていますので、printで正常な動作が見られたら以下のように置き換えるつもりです。
Serial.write(buf[0]); for (int i = 1; i < 48; i++) { if (buf[i] == HEAD_BYTE | buf[i] == ESCAPE_BYTE) { Serial.write(ESCAPE_BYTE); Serial.write(buf[i] ^ ESCAPE_MASK); } else { Serial.write(buf[i]); } }
試したこと
dataAquisition()関数の中に以下のようにシリアルプリントを挿入したらうまくいきました。
arudino
1void dataAquisition() { 2 int rud = analogRead(r_pin); 3 int elv = analogRead(e_pin); 4 5 data[0] = rud; 6 data[1] = elv; 7 getrpm(); 8 Serial.println("get rpm"); 9 getHeight(); 10 Serial.println("get Height"); 11 getAttitude(); 12 Serial.println("get Attitude"); 13 getGPS(); 14 Serial.println("get GPS"); 15 getBaro(); 16 Serial.println("get Baro"); 17 getASpeed(); 18 Serial.println("get AirSpeed"); 19 data[13] = -13.32; 20 data[14] = 1.26; 21 data[15] = -2.1; 22 data[16] = 1.23; 23 data[17] = 7.86; 24}
ただ、最終的には余計なデータ送信をしたくないのでこれらのデバッグ用のシリアル送信は削除したいと思っています。Serial.printlnの有無で挙動が変わるというのも不可解です。
####追記
プログラムが止まるタイミングからgetGPS()関数が怪しいと思いコメントアウトしてみたところ、デバッグ用のシリアル通信を削除した上でバイナリデータの送信が成功しました。getGPS()関数は以下になります。
void getGPS() { String line; String s; double LAT; //緯度 double LNG; //経度 double GS; //対地速度 GPSSerial.listen(); while (!GPSSerial.isListening()); //1つのセンテンスを読み込む do { String line = GPSSerial.readStringUntil('\n'); if (line != "") { int i, index = 0, len = line.length(); String str = ""; //Stringlist生成 String list[30]; for (i = 0; i < 30; i++) { list[i] = ""; } //「,」を区切り文字として文字列を配列にする for (i = 0; i < len; i++) { if (line[i] == ',') { list[index++] = str; str = ""; continue; } str += line[i]; } //$GPRMCセンテンスを読み込んで、緯度、経度、対地速を表示する if (list[0] == "$GPRMC") { //素子に応じて$以下の部分を変える if (list[2] == "A") { //GPSが測位不可でない時 //緯度 LAT = NMEA2DD(list[3].toFloat()), 6; //経度 LNG = NMEA2DD(list[5].toFloat()), 6; //対地速(km/h) GS = list[7].toFloat() * 1.852; //1ノット=1.852km/h } s += String(LAT, 6); s += String(LNG, 6); s += (String)GS; data[7] = LAT; data[8] = LNG; data[9] = GS; } } } while (s == ""); //ちゃんと読めるまで } //NMEAの緯度経度を「度」(DD)の表記に変換 float NMEA2DD(float val) { float u; int d = val / 100; int m = (((val / 100.0) - d) * 100.0) / 60; float s = (((((val / 100.0) - d) * 100.0) - m) * 60) / (60 * 60); u = d + m + s; return u; }
秋月電子通商で販売されているGPSモジュールを使用しています。通信にはソフトウェアシリアルを使用しています。
補足情報(FW/ツールのバージョンなど)
dataAquisition()関数内のget○○の関数すべてが正常に動作することは確認されています。また、バイナリデータへ変換するRecordbuf()も正常に動作することが確認できています。
ただ、これらを組み合わせたときに上記の問題が発生しました。

回答3件
あなたの回答
tips
プレビュー