edits in camera

code_midgen
EmaMaker 2020-03-09 17:10:22 +01:00
parent dddbbc1810
commit b891d8c803
10 changed files with 953 additions and 209 deletions

View File

@ -2,8 +2,10 @@
#include "position/systems.h" #include "position/systems.h"
#define CAMERA_CENTER_X 10 #define CAMERA_CENTER_X 0
#define CAMERA_CENTER_Y -13 #define CAMERA_CENTER_Y 0
#define CAMERA_GOAL_X 0
#define CAMERA_GOAL_Y -13
#define CAMERA_CENTER_Y_ABS_SUM 72 #define CAMERA_CENTER_Y_ABS_SUM 72
//Actually it's ± MAX_VAL //Actually it's ± MAX_VAL
#define MAX_X 25 #define MAX_X 25

View File

@ -17,6 +17,7 @@ class DataSourceCameraConic : public DataSource{
DataSourceCameraConic(HardwareSerial* ser, int baud); DataSourceCameraConic(HardwareSerial* ser, int baud);
void test() override; void test() override;
void readSensor() override; void readSensor() override;
void computeCoordsAngles();
// int getValueAtk(bool); // int getValueAtk(bool);
// int getValueDef(bool); // int getValueDef(bool);

View File

@ -23,6 +23,8 @@ void loop() {
goalie->play(role==1); goalie->play(role==1);
keeper->play(role==0); keeper->play(role==0);
camera->test();
// Last thing to do: movement and update status vector // Last thing to do: movement and update status vector
drive->drivePrepared(); drive->drivePrepared();
updateStatusVector(); updateStatusVector();

View File

@ -45,81 +45,10 @@ void DataSourceCameraConic ::readSensor() {
true_yb = yb; true_yb = yb;
true_xy = xy; true_xy = xy;
true_yy = yy; true_yy = yy;
//Where are the goals relative to the robot?
true_xb = 50 - true_xb;
true_yb = true_yb - 50;
true_xy = 50 - true_xy;
true_yy = true_yy - 50;
//Remap from [0,100] to [-50, +50] to correctly compute angles and distances and calculate them
yAngle = 90 - (atan2(true_yy, true_xy) * 180 / 3.14);
bAngle = 90 - (atan2(true_yb, true_xb) * 180 / 3.14);
//Now cast angles to [0, 359] domain angle flip them
yAngle = (yAngle + 360) % 360;
bAngle = (bAngle + 360) % 360;
yDist = sqrt((true_yy) * (true_yy) + (true_xy) * (true_xy));
bDist = sqrt((true_yb) * (true_yb) + (true_xb) * (true_xb));
//Rotate the point on the cartesian plane to compensate the robot tilt
// float angleFix = CURRENT_DATA_READ.IMUAngle*IMUTOC_AMULT;
// angleFix = (angleFix * 3.14) / 180;
// float angleFix = CURRENT_DATA_READ.IMUAngle*3.14/180;
// true_xb_fixed = (true_xb*(cos(angleFix))) - (true_yb*(sin(angleFix)));
// true_yb_fixed = (true_xb*(sin(angleFix))) + (true_yb*(cos(angleFix)));
// true_xy_fixed = (true_xy*(cos(angleFix))) - (true_yy*(sin(angleFix)));
// true_yy_fixed = (true_xy*(sin(angleFix))) + (true_yy*(cos(angleFix)));
int angleFix = CURRENT_DATA_READ.IMUAngle > 180 ? CURRENT_DATA_READ.IMUAngle - 360 : CURRENT_DATA_READ.IMUAngle;
//Fixes with IMU
yAngleFix = ((int)((yAngle + angleFix * 0.8)) + 360) % 360;
bAngleFix = ((int)((bAngle + angleFix * 0.8)) + 360) % 360;
//Important: update status vector
CURRENT_INPUT_WRITE.cameraByte = value;
CURRENT_DATA_WRITE.cam_xb = true_xb;
CURRENT_DATA_WRITE.cam_yb = true_yb;
CURRENT_DATA_WRITE.cam_xy = true_xy;
CURRENT_DATA_WRITE.cam_yy = true_yy;
CURRENT_DATA_WRITE.cam_xb_fixed = true_xb_fixed;
CURRENT_DATA_WRITE.cam_yb_fixed = true_yb_fixed;
CURRENT_DATA_WRITE.cam_xy_fixed = true_xy_fixed;
CURRENT_DATA_WRITE.cam_yy_fixed = true_yy_fixed;
CURRENT_DATA_WRITE.yAngle = yAngle;
CURRENT_DATA_WRITE.bAngle = bAngle;
CURRENT_DATA_WRITE.yAngleFix = yAngleFix;
CURRENT_DATA_WRITE.bAngleFix = bAngleFix;
CURRENT_DATA_WRITE.yDist = yDist;
CURRENT_DATA_WRITE.bDist = bDist;
if (xb == unkn || yb == unkn) CURRENT_DATA_WRITE.bSeen = false;
else CURRENT_DATA_WRITE.bSeen = true;
if (xy == unkn || yy == unkn) CURRENT_DATA_WRITE.ySeen = false;
else CURRENT_DATA_WRITE.ySeen = true;
if (goalOrientation == HIGH) {
CURRENT_DATA_WRITE.angleAtk = CURRENT_DATA_WRITE.yAngle;
CURRENT_DATA_WRITE.angleAtkFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.atkSeen = CURRENT_DATA_WRITE.ySeen;
CURRENT_DATA_WRITE.angleDef = CURRENT_DATA_WRITE.bAngle;
CURRENT_DATA_WRITE.angleDefFix = CURRENT_DATA_WRITE.bAngleFix;
CURRENT_DATA_WRITE.defSeen = CURRENT_DATA_WRITE.bSeen;
} else {
CURRENT_DATA_WRITE.angleAtk = CURRENT_DATA_WRITE.bAngle;
CURRENT_DATA_WRITE.angleAtkFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.atkSeen = CURRENT_DATA_WRITE.bSeen;
CURRENT_DATA_WRITE.angleDef = CURRENT_DATA_WRITE.yAngle;
CURRENT_DATA_WRITE.angleDefFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.defSeen = CURRENT_DATA_WRITE.ySeen;
}
} }
end = true; end = true;
start = false; start = false;
} } else{
else{
if (start == true) if (start == true)
{ {
if (count == 0) if (count == 0)
@ -136,14 +65,80 @@ void DataSourceCameraConic ::readSensor() {
} }
} }
// int DataSource<CameraConic::getValueAtk(bool fixed){
// if(fixed) return goalOrientation == HIGH ? yAngleFix : bAngleFix; void DataSourceCameraConic ::computeCoordsAngles() {
// else return goalOrientation == HIGH ? yAngle : bAngle; //Where are the goals relative to the robot?
// } //Remap from [0,100] to [-50, +50] to correctly compute angles and distances and calculate them, getting the original coords calculated by the camera
// int DataSourceCameraConic::getValueDef(bool fixed){ true_xb = 50 - true_xb;
// if(fixed) return goalOrientation == LOW ? yAngleFix : bAngleFix; true_yb = true_yb - 50;
// else return goalOrientation == LOW ? yAngle : bAngle; true_xy = 50 - true_xy;
// }> true_yy = true_yy - 50;
yAngle = 90 - (atan2(true_yy, true_xy) * 180 / 3.14);
bAngle = 90 - (atan2(true_yb, true_xb) * 180 / 3.14);
//Now cast angles to [0, 359] domain angle flip them
yAngle = (yAngle + 360) % 360;
bAngle = (bAngle + 360) % 360;
yDist = sqrt((true_yy) * (true_yy) + (true_xy) * (true_xy));
bDist = sqrt((true_yb) * (true_yb) + (true_xb) * (true_xb));
// int angleFix = CURRENT_DATA_READ.IMUAngle > 180 ? CURRENT_DATA_READ.IMUAngle - 360 : CURRENT_DATA_READ.IMUAngle;
// //Fixes with IMU
// yAngleFix = ((int)((yAngle + angleFix * 0.8)) + 360) % 360;
// bAngleFix = ((int)((bAngle + angleFix * 0.8)) + 360) % 360;
//Rotate the points of the goals on the cartesian plane to compensate the robot tilt
int tmp = CURRENT_DATA_READ.IMUAngle > 180 ? CURRENT_DATA_READ.IMUAngle - 360 : CURRENT_DATA_READ.IMUAngle;
//We are considering the angle being negative if going counterclockwise and positive is going clockwise.
//The formula used below assumes the angle being positive in counterclockwise and negative in clockwise, so the angle must be multiplied by -1
//A little explanation of the formula used here can be found on wikipedia: https://en.wikipedia.org/wiki/Rotation_of_axes
float angleFix = -tmp*3.14/180;
true_xb_fixed = (true_xb*(cos(angleFix))) - (true_yb*(sin(angleFix)));
true_yb_fixed = (true_xb*(sin(angleFix))) + (true_yb*(cos(angleFix)));
true_xy_fixed = (true_xy*(cos(angleFix))) - (true_yy*(sin(angleFix)));
true_yy_fixed = (true_xy*(sin(angleFix))) + (true_yy*(cos(angleFix)));
yAngleFix = 90 - (atan2(true_yy_fixed, true_xy_fixed) * 180 / 3.14);
bAngleFix = 90 - (atan2(true_yb_fixed, true_xb_fixed) * 180 / 3.14);
//Important: update status vector
CURRENT_INPUT_WRITE.cameraByte = value;
CURRENT_DATA_WRITE.cam_xb = true_xb;
CURRENT_DATA_WRITE.cam_yb = true_yb;
CURRENT_DATA_WRITE.cam_xy = true_xy;
CURRENT_DATA_WRITE.cam_yy = true_yy;
CURRENT_DATA_WRITE.cam_xb_fixed = true_xb_fixed;
CURRENT_DATA_WRITE.cam_yb_fixed = true_yb_fixed;
CURRENT_DATA_WRITE.cam_xy_fixed = true_xy_fixed;
CURRENT_DATA_WRITE.cam_yy_fixed = true_yy_fixed;
CURRENT_DATA_WRITE.yAngle = yAngle;
CURRENT_DATA_WRITE.bAngle = bAngle;
CURRENT_DATA_WRITE.yAngleFix = yAngleFix;
CURRENT_DATA_WRITE.bAngleFix = bAngleFix;
CURRENT_DATA_WRITE.yDist = yDist;
CURRENT_DATA_WRITE.bDist = bDist;
if (xb == unkn || yb == unkn) CURRENT_DATA_WRITE.bSeen = false;
else CURRENT_DATA_WRITE.bSeen = true;
if (xy == unkn || yy == unkn) CURRENT_DATA_WRITE.ySeen = false;
else CURRENT_DATA_WRITE.ySeen = true;
if (goalOrientation == HIGH) {
CURRENT_DATA_WRITE.angleAtk = CURRENT_DATA_WRITE.yAngle;
CURRENT_DATA_WRITE.angleAtkFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.atkSeen = CURRENT_DATA_WRITE.ySeen;
CURRENT_DATA_WRITE.angleDef = CURRENT_DATA_WRITE.bAngle;
CURRENT_DATA_WRITE.angleDefFix = CURRENT_DATA_WRITE.bAngleFix;
CURRENT_DATA_WRITE.defSeen = CURRENT_DATA_WRITE.bSeen;
} else {
CURRENT_DATA_WRITE.angleAtk = CURRENT_DATA_WRITE.bAngle;
CURRENT_DATA_WRITE.angleAtkFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.atkSeen = CURRENT_DATA_WRITE.bSeen;
CURRENT_DATA_WRITE.angleDef = CURRENT_DATA_WRITE.yAngle;
CURRENT_DATA_WRITE.angleDefFix = CURRENT_DATA_WRITE.yAngleFix;
CURRENT_DATA_WRITE.defSeen = CURRENT_DATA_WRITE.ySeen;
}
}
void DataSourceCameraConic::test(){ void DataSourceCameraConic::test(){
goalOrientation = digitalRead(SWITCH_SX); //se HIGH attacco gialla, difendo blu goalOrientation = digitalRead(SWITCH_SX); //se HIGH attacco gialla, difendo blu

View File

@ -84,7 +84,7 @@ while(True):
tt_blue = [(0,999,0,2)] ## creo una lista di tuple per il blue, valore x = 999 : non trovata tt_blue = [(0,999,0,2)] ## creo una lista di tuple per il blue, valore x = 999 : non trovata
img = sensor.snapshot() img = sensor.snapshot()
for blob in img.find_blobs(thresholds, pixels_threshold=60, area_threshold=90, merge = True): for blob in img.find_blobs(thresholds, pixels_threshold=40, area_threshold=50, merge = True):
img.draw_rectangle(blob.rect()) img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy()) img.draw_cross(blob.cx(), blob.cy())

View File

@ -0,0 +1,142 @@
:1000000072C000009EC000009CC000009AC00000AA
:1000100098C0000096C0000094C0000092C000008C
:1000200090C000004AC3000048C3000046C300005F
:1000300088C0000086C0000084C0000082C00000AC
:1000400080C000007EC000007CC000007AC00000BC
:1000500078C0000076C0000074C00000E4C2000058
:1000600070C00000AAC200007FC200006AC0000089
:1000700068C0000066C0000064C0000062C00000EC
:1000800060C000005EC000005CC000005AC00000FC
:1000900058C0000056C0000054C0000052C000000C
:1000A00050C000004EC000004CC000004AC000001C
:1000B00048C0000046C0000044C0000042C000002C
:1000C00040C000003EC000003CC000003AC000003C
:1000D00038C0000036C0000011C20000E6C10000B8
:1000E00030C00000670311241FBECFEFD1E2DEBF96
:1000F000CDBF00E00CBF12E0A0E0B2E0E0EBF8E022
:1001000000E00BBF02C007900D92A231B107D9F7F2
:1001100023E0A2E1B2E001C01D92A735B207E1F7EA
:1001200010E0C3E7D0E000E005C021970109802F6F
:10013000FE01B4D3C237D10780E00807B1F71AD364
:10014000B5C35ECFFC01A089B18982E08C93A48500
:10015000B5851C92A685B7858FEC8C93108EA489EB
:10016000B58986E08C93A289B3898C9180618C9348
:10017000A289B3898C9188608C93A289B3898C9170
:1001800080688C930288F389E02D80818F7D808345
:100190000895AF92BF92CF92DF92EF92FF920F93AA
:1001A0001F93CF93DF936C017B018B01040F151F0D
:1001B000EB015E01AE18BF08C017D10759F0699175
:1001C000D601ED91FC910190F081E02DC6011995C9
:1001D000892B79F7C501DF91CF911F910F91FF9086
:1001E000EF90DF90CF90BF90AF900895FC01538DBA
:1001F000448D252F30E0842F90E0821B930B541701
:1002000010F0CF96089501970895FC01918D828D8D
:10021000981761F0A28DAE0FBF2FB11D5D968C9126
:10022000928D9F5F9F73928F90E008958FEF9FEF65
:100230000895FC01918D828D981731F0828DE80F21
:10024000F11D858D90E008958FEF9FEF0895FC01DB
:10025000918D228D892F90E0805C9F4F821B9109A8
:100260008F73992708958DE192E0F1DF21E0892BCA
:1002700009F420E0822F08958AEB92E0E8DF21E084
:10028000892B09F420E0822F0895FC01A48DA80F8A
:10029000B92FB11DA35ABF4F2C91848D90E00196C8
:1002A0008F739927848FA689B7892C93A089B189E8
:1002B0008C91837080648C93938D848D981306C089
:1002C0000288F389E02D80818F7D80830895EF92ED
:1002D000FF920F931F93CF93DF93EC0181E0888F00
:1002E0009B8D8C8D98131AC0E889F989808185FFD0
:1002F00015C09FB7F894EE89FF896083E889F98972
:1003000080818370806480839FBF81E090E0DF9173
:10031000CF911F910F91FF90EF900895F62E0B8DC6
:1003200010E00F5F1F4F0F731127E02E8C8D8E1181
:100330000BC00FB607FCFACFE889F989808185FFE9
:10034000F5CFCE01A2DFF2CFEB8DEC0FFD2FF11D2B
:10035000E35AFF4FF0829FB7F8940B8FEA89FB892D
:1003600080818062D0CFCF93DF93EC01888D88238A
:10037000B1F0AA89BB89E889F9898C9185FD03C010
:10038000808186FD0CC00FB607FCF7CF8C9185FFEE
:10039000F2CF808185FFEDCFCE0177DFEACFDF910D
:1003A000CF91089580E090E0892B21F065DF8111E5
:1003B0000E94000080E090E0892B49F080E090E00E
:1003C000892B29F00E94000081110E94000080E02A
:1003D00090E0892B49F080E090E0892B29F00E9481
:1003E000000081110E94000080E090E0892B21F044
:1003F0003ADF81110C94000008953FB7F894809182
:10040000190290911A02A0911B02B0911C0226B50C
:10041000A89B05C02F3F19F00196A11DB11D3FBF3C
:10042000BA2FA92F982F8827BC01CD01620F711D0B
:10043000811D911D42E0660F771F881F991F4A9505
:10044000D1F708958F929F92AF92BF92CF92DF9291
:10045000EF92FF92D2DF4B015C0182E3C82ED12CD8
:10046000E12CF12CCADF681979098A099B09683ED9
:10047000734081059105B0F321E0C21AD108E1086B
:10048000F10888EE880E83E0981EA11CB11CC114EF
:10049000D104E104F10431F7FF90EF90DF90CF90A9
:1004A000BF90AF909F908F9008951F920F920FB6BC
:1004B0000F9211240BB60F922F933F934F935F939C
:1004C0006F937F938F939F93AF93BF93EF93FF931C
:1004D0008DE192E0DADEFF91EF91BF91AF919F91B4
:1004E0008F917F916F915F914F913F912F910F90DD
:1004F0000BBE0F900FBE0F901F9018951F920F927A
:100500000FB60F9211240BB60F922F938F939F93D8
:10051000EF93FF93E0912D02F0912E028081E09104
:100520003302F091340282FD1DC090818091360229
:100530008F5F8F7320913702821741F0E09136026E
:10054000F0E0E35EFD4F958F80933602FF91EF91CF
:100550009F918F912F910F900BBE0F900FBE0F9018
:100560001F9018958081F2CF1F920F920FB60F92B5
:1005700011240BB60F922F933F934F935F936F937A
:100580007F938F939F93AF93BF93EF93FF938AEBE8
:1005900092E07BDEFF91EF91BF91AF919F918F91A0
:1005A0007F916F915F914F913F912F910F900BBE73
:1005B0000F900FBE0F901F9018951F920F920FB6BD
:1005C0000F9211240BB60F922F938F939F93EF935B
:1005D000FF93E091CA02F091CB028081E091D002BA
:1005E000F091D10282FD1DC090818091D3028F5F76
:1005F0008F732091D402821741F0E091D302F0E092
:10060000E654FD4F958F8093D302FF91EF919F9118
:100610008F912F910F900BBE0F900FBE0F901F90D8
:1006200018958081F2CF1F920F920FB60F9211246E
:100630002F933F938F939F93AF93BF938091150216
:1006400090911602A0911702B091180230911402F5
:1006500023E0230F2D3758F50196A11DB11D2093DE
:1006600014028093150290931602A0931702B09380
:1006700018028091190290911A02A0911B02B09168
:100680001C020196A11DB11D8093190290931A02BC
:10069000A0931B02B0931C02BF91AF919F918F91C9
:1006A0003F912F910F900FBE0F901F90189526E845
:1006B000230F0296A11DB11DD2CF1F920F920FB62C
:1006C0000F9211240F900FBE0F901F901895EDE11F
:1006D000F2E01382128248EE53E060E070E044835F
:1006E00055836683778384E092E09183808325E35A
:1006F00031E03587248724E331E03787268720E3FC
:1007000031E0318B208B21E331E0338B228B22E3EC
:1007100031E0358B248B26E331E0378B268B118E2D
:10072000128E138E148EEAEBF2E01382128244834F
:100730005583668377839183808385EC90E09587EA
:10074000848784EC90E09787868780EC90E0918B9B
:10075000808B81EC90E0938B828B82EC90E0958B88
:10076000848B86EC90E0978B868B118E128E138E85
:10077000148E0895789484B5826084BD84B58160B8
:1007800084BD85B5826085BD85B5816085BD80915C
:100790006E00816080936E001092810080918100D4
:1007A00082608093810080918100816080938100CC
:1007B000809180008160809380008091B10084608E
:1007C0008093B1008091B00081608093B0008091EF
:1007D000910082608093910080919100816080936C
:1007E0009100809190008160809390008091A100A1
:1007F00082608093A1008091A10081608093A1001C
:100800008091A00081608093A0008091210182608E
:100810008093210180912101816080932101809149
:10082000200181608093200180917A008460809310
:100830007A0080917A00826080937A0080917A00B9
:10084000816080937A0080917A00806880937A003A
:100850001092C1008AEB92E075DC8DE192E072DCCF
:100860008DE192E0F4DC892B49F08DE192E0CDDC62
:10087000682F8AEB92E02BDDE5DDF2CF8AEB92E088
:10088000E6DC892B49F08AEB92E0BFDC682F8DE132
:1008900092E01DDDD7DDF2CF85DDE2CFEE0FFF1F49
:1008A000881F8BBF0790F691E02D1994F894FFCF25
:1008B000000000006701C900F600B301270105012F
:0208C00019011C
:00000001FF

View File

@ -0,0 +1,610 @@
:1000000072C000009EC000009CC000009AC00000AA
:1000100098C0000096C0000094C0000092C000008C
:1000200090C000004AC3000048C3000046C300005F
:1000300088C0000086C0000084C0000082C00000AC
:1000400080C000007EC000007CC000007AC00000BC
:1000500078C0000076C0000074C00000E4C2000058
:1000600070C00000AAC200007FC200006AC0000089
:1000700068C0000066C0000064C0000062C00000EC
:1000800060C000005EC000005CC000005AC00000FC
:1000900058C0000056C0000054C0000052C000000C
:1000A00050C000004EC000004CC000004AC000001C
:1000B00048C0000046C0000044C0000042C000002C
:1000C00040C000003EC000003CC000003AC000003C
:1000D00038C0000036C0000011C20000E6C10000B8
:1000E00030C00000670311241FBECFEFD1E2DEBF96
:1000F000CDBF00E00CBF12E0A0E0B2E0E0EBF8E022
:1001000000E00BBF02C007900D92A231B107D9F7F2
:1001100023E0A2E1B2E001C01D92A735B207E1F7EA
:1001200010E0C3E7D0E000E005C021970109802F6F
:10013000FE01B4D3C237D10780E00807B1F71AD364
:10014000B5C35ECFFC01A089B18982E08C93A48500
:10015000B5851C92A685B7858FEC8C93108EA489EB
:10016000B58986E08C93A289B3898C9180618C9348
:10017000A289B3898C9188608C93A289B3898C9170
:1001800080688C930288F389E02D80818F7D808345
:100190000895AF92BF92CF92DF92EF92FF920F93AA
:1001A0001F93CF93DF936C017B018B01040F151F0D
:1001B000EB015E01AE18BF08C017D10759F0699175
:1001C000D601ED91FC910190F081E02DC6011995C9
:1001D000892B79F7C501DF91CF911F910F91FF9086
:1001E000EF90DF90CF90BF90AF900895FC01538DBA
:1001F000448D252F30E0842F90E0821B930B541701
:1002000010F0CF96089501970895FC01918D828D8D
:10021000981761F0A28DAE0FBF2FB11D5D968C9126
:10022000928D9F5F9F73928F90E008958FEF9FEF65
:100230000895FC01918D828D981731F0828DE80F21
:10024000F11D858D90E008958FEF9FEF0895FC01DB
:10025000918D228D892F90E0805C9F4F821B9109A8
:100260008F73992708958DE192E0F1DF21E0892BCA
:1002700009F420E0822F08958AEB92E0E8DF21E084
:10028000892B09F420E0822F0895FC01A48DA80F8A
:10029000B92FB11DA35ABF4F2C91848D90E00196C8
:1002A0008F739927848FA689B7892C93A089B189E8
:1002B0008C91837080648C93938D848D981306C089
:1002C0000288F389E02D80818F7D80830895EF92ED
:1002D000FF920F931F93CF93DF93EC0181E0888F00
:1002E0009B8D8C8D98131AC0E889F989808185FFD0
:1002F00015C09FB7F894EE89FF896083E889F98972
:1003000080818370806480839FBF81E090E0DF9173
:10031000CF911F910F91FF90EF900895F62E0B8DC6
:1003200010E00F5F1F4F0F731127E02E8C8D8E1181
:100330000BC00FB607FCFACFE889F989808185FFE9
:10034000F5CFCE01A2DFF2CFEB8DEC0FFD2FF11D2B
:10035000E35AFF4FF0829FB7F8940B8FEA89FB892D
:1003600080818062D0CFCF93DF93EC01888D88238A
:10037000B1F0AA89BB89E889F9898C9185FD03C010
:10038000808186FD0CC00FB607FCF7CF8C9185FFEE
:10039000F2CF808185FFEDCFCE0177DFEACFDF910D
:1003A000CF91089580E090E0892B21F065DF8111E5
:1003B0000E94000080E090E0892B49F080E090E00E
:1003C000892B29F00E94000081110E94000080E02A
:1003D00090E0892B49F080E090E0892B29F00E9481
:1003E000000081110E94000080E090E0892B21F044
:1003F0003ADF81110C94000008953FB7F894809182
:10040000190290911A02A0911B02B0911C0226B50C
:10041000A89B05C02F3F19F00196A11DB11D3FBF3C
:10042000BA2FA92F982F8827BC01CD01620F711D0B
:10043000811D911D42E0660F771F881F991F4A9505
:10044000D1F708958F929F92AF92BF92CF92DF9291
:10045000EF92FF92D2DF4B015C0182E3C82ED12CD8
:10046000E12CF12CCADF681979098A099B09683ED9
:10047000734081059105B0F321E0C21AD108E1086B
:10048000F10888EE880E83E0981EA11CB11CC114EF
:10049000D104E104F10431F7FF90EF90DF90CF90A9
:1004A000BF90AF909F908F9008951F920F920FB6BC
:1004B0000F9211240BB60F922F933F934F935F939C
:1004C0006F937F938F939F93AF93BF93EF93FF931C
:1004D0008DE192E0DADEFF91EF91BF91AF919F91B4
:1004E0008F917F916F915F914F913F912F910F90DD
:1004F0000BBE0F900FBE0F901F9018951F920F927A
:100500000FB60F9211240BB60F922F938F939F93D8
:10051000EF93FF93E0912D02F0912E028081E09104
:100520003302F091340282FD1DC090818091360229
:100530008F5F8F7320913702821741F0E09136026E
:10054000F0E0E35EFD4F958F80933602FF91EF91CF
:100550009F918F912F910F900BBE0F900FBE0F9018
:100560001F9018958081F2CF1F920F920FB60F92B5
:1005700011240BB60F922F933F934F935F936F937A
:100580007F938F939F93AF93BF93EF93FF938AEBE8
:1005900092E07BDEFF91EF91BF91AF919F918F91A0
:1005A0007F916F915F914F913F912F910F900BBE73
:1005B0000F900FBE0F901F9018951F920F920FB6BD
:1005C0000F9211240BB60F922F938F939F93EF935B
:1005D000FF93E091CA02F091CB028081E091D002BA
:1005E000F091D10282FD1DC090818091D3028F5F76
:1005F0008F732091D402821741F0E091D302F0E092
:10060000E654FD4F958F8093D302FF91EF919F9118
:100610008F912F910F900BBE0F900FBE0F901F90D8
:1006200018958081F2CF1F920F920FB60F9211246E
:100630002F933F938F939F93AF93BF938091150216
:1006400090911602A0911702B091180230911402F5
:1006500023E0230F2D3758F50196A11DB11D2093DE
:1006600014028093150290931602A0931702B09380
:1006700018028091190290911A02A0911B02B09168
:100680001C020196A11DB11D8093190290931A02BC
:10069000A0931B02B0931C02BF91AF919F918F91C9
:1006A0003F912F910F900FBE0F901F90189526E845
:1006B000230F0296A11DB11DD2CF1F920F920FB62C
:1006C0000F9211240F900FBE0F901F901895EDE11F
:1006D000F2E01382128248EE53E060E070E044835F
:1006E00055836683778384E092E09183808325E35A
:1006F00031E03587248724E331E03787268720E3FC
:1007000031E0318B208B21E331E0338B228B22E3EC
:1007100031E0358B248B26E331E0378B268B118E2D
:10072000128E138E148EEAEBF2E01382128244834F
:100730005583668377839183808385EC90E09587EA
:10074000848784EC90E09787868780EC90E0918B9B
:10075000808B81EC90E0938B828B82EC90E0958B88
:10076000848B86EC90E0978B868B118E128E138E85
:10077000148E0895789484B5826084BD84B58160B8
:1007800084BD85B5826085BD85B5816085BD80915C
:100790006E00816080936E001092810080918100D4
:1007A00082608093810080918100816080938100CC
:1007B000809180008160809380008091B10084608E
:1007C0008093B1008091B00081608093B0008091EF
:1007D000910082608093910080919100816080936C
:1007E0009100809190008160809390008091A100A1
:1007F00082608093A1008091A10081608093A1001C
:100800008091A00081608093A0008091210182608E
:100810008093210180912101816080932101809149
:10082000200181608093200180917A008460809310
:100830007A0080917A00826080937A0080917A00B9
:10084000816080937A0080917A00806880937A003A
:100850001092C1008AEB92E075DC8DE192E072DCCF
:100860008DE192E0F4DC892B49F08DE192E0CDDC62
:10087000682F8AEB92E02BDDE5DDF2CF8AEB92E088
:10088000E6DC892B49F08AEB92E0BFDC682F8DE132
:1008900092E01DDDD7DDF2CF85DDE2CFEE0FFF1F49
:1008A000881F8BBF0790F691E02D1994F894FFCF25
:1008B000000000006701C900F600B301270105012F
:0208C00019011C
:020000023000CC
:10E000000D9489F10D94B2F10D94B2F10D94B2F129
:10E010000D94B2F10D94B2F10D94B2F10D94B2F1F0
:10E020000D94B2F10D94B2F10D94B2F10D94B2F1E0
:10E030000D94B2F10D94B2F10D94B2F10D94B2F1D0
:10E040000D94B2F10D94B2F10D94B2F10D94B2F1C0
:10E050000D94B2F10D94B2F10D94B2F10D94B2F1B0
:10E060000D94B2F10D94B2F10D94B2F10D94B2F1A0
:10E070000D94B2F10D94B2F10D94B2F10D94B2F190
:10E080000D94B2F10D94B2F10D94B2F10D94B2F180
:10E090000D94B2F10D94B2F10D94B2F10D94B2F170
:10E0A0000D94B2F10D94B2F10D94B2F10D94B2F160
:10E0B0000D94B2F10D94B2F10D94B2F10D94B2F150
:10E0C0000D94B2F10D94B2F10D94B2F10D94B2F140
:10E0D0000D94B2F10D94B2F10D94B2F10D94B2F130
:10E0E0000D94B2F141546D656761323536300041AF
:10E0F000726475696E6F206578706C6F72657220DE
:10E1000073746B3530305632206279204D4C530099
:10E11000426F6F746C6F616465723E004875683F52
:10E1200000436F6D70696C6564206F6E203D200048
:10E130004350552054797065202020203D20005FF9
:10E140005F4156525F415243485F5F3D2000415658
:10E1500052204C696243205665723D20004743437C
:10E160002056657273696F6E203D20004350552024
:10E1700049442020202020203D20004C6F7720663D
:10E18000757365202020203D20004869676820665F
:10E190007573652020203D200045787420667573D6
:10E1A00065202020203D20004C6F636B2066757336
:10E1B000652020203D20004D617220203720323024
:10E1C000313300312E362E3800342E332E350056A2
:10E1D00023202020414444522020206F7020636F70
:10E1E00064652020202020696E73747275637469E1
:10E1F0006F6E2061646472202020496E74657272B3
:10E20000757074006E6F20766563746F7200726A49
:10E210006D702020006A6D70200057686174207056
:10E220006F72743A00506F7274206E6F7420737541
:10E2300070706F72746564004D7573742062652030
:10E2400061206C6574746572002000577269747483
:10E25000696E672045450052656164696E672045B7
:10E26000450045452065727220636E743D00504F35
:10E27000525400303D5A65726F2061646472003FF1
:10E280003D43505520737461747300403D454550C3
:10E29000524F4D207465737400423D426C696E6B41
:10E2A000204C454400453D44756D70204545505215
:10E2B0004F4D00463D44756D7020464C415348001B
:10E2C000483D48656C70004C3D4C69737420492F83
:10E2D0004F20506F72747300513D51756974005234
:10E2E0003D44756D702052414D00563D73686F7707
:10E2F00020696E7465727275707420566563746FF0
:10E30000727300593D506F727420626C696E6B00BD
:10E310002A0011241FBECFEFD1E2DEBFCDBF01E046
:10E320000CBF12E0A0E0B2E0EEE1FDEF03E00BBFB6
:10E3300002C007900D92A030B107D9F712E0A0E01B
:10E34000B2E001C01D92AE30B107E1F70F9460F367
:10E350000D948DFE01E20EBF0FEF0DBF11241FBE05
:10E360000D9460F30D9400F020E030E040ED57E0B4
:10E3700005C0FA013197F1F72F5F3F4F2817390792
:10E38000C0F308959C01260F311DC901A0E0B0E043
:10E390002F5F3F4FABBFFC018791882361F08093D3
:10E3A000C6008091C00086FFFCCF8091C0008064D1
:10E3B0008093C000EACF08958DE08093C6008091DD
:10E3C000C00086FFFCCF8091C00080648093C000B5
:10E3D0008AE08093C6008091C00086FFFCCF8091C8
:10E3E000C00080648093C00008950F94C2F10F9420
:10E3F000DCF10895FC019081992359F09093C600B7
:10E400008091C00086FFFCCF8091C0008064809323
:10E41000C0003196992379F70895282F982F929567
:10E420009F70892F805D8A3308F0895F8093C600D2
:10E430008091C00086FFFCCF8091C00080648093F3
:10E44000C000822F8F70982F905D9A3308F0995FEB
:10E450009093C6008091C00086FFFCCF8091C000E1
:10E4600080648093C00008959C01FB01853691056E
:10E470001CF46330710594F0C90164E670E00F94F8
:10E480002EFE605D7F4F6093C6008091C00086FFC6
:10E49000FCCF8091C00080648093C0002B30310598
:10E4A00014F43297B4F0C90164E670E00F942EFEC4
:10E4B0006AE070E00F942EFE605D7F4F6093C600AF
:10E4C0008091C00086FFFCCF8091C0008064809363
:10E4D000C000C9016AE070E00F942EFEC0968093E0
:10E4E000C6008091C00086FFFCCF8091C000806490
:10E4F0008093C00008951F93182F8EE692EE60E07F
:10E500000F94C2F11093C6008091C00086FFFCCF2B
:10E510008091C00080648093C0000F94DCF11F9153
:10E5200008952F923F924F925F926F927F928F92B7
:10E530009F92AF92BF92CF92DF92EF92FF920F9392
:10E540001F93DF93CF93CDB7DEB762970FB6F894E2
:10E55000DEBF0FBECDBF382E622ECA01DB015C01CB
:10E560006D01772420E2222E2E010894411C511CBB
:10E570008BC081E0A81680E0B80681E0C80680E084
:10E58000D80628F0C601AA27BB270F940DF2BB2797
:10E59000AD2D9C2D8B2D0F940DF28A2D0F940DF225
:10E5A0002092C6008091C00086FFFCCF8091C00001
:10E5B00080648093C0009DE29093C6008091C0006B
:10E5C00086FFFCCF8091C00080648093C0002092C1
:10E5D000C6008091C00086FFFCCF8091C00080649F
:10E5E0008093C00019828601750188249924A1E0D6
:10E5F0003A1651F03A1620F0B2E03B1661F409C029
:10E600000BBFF701779007C0C7010F9477FE782EF4
:10E6100002C0F7017080872D0F940DF22092C60082
:10E620008091C00086FFFCCF8091C0008064809301
:10E63000C000872D8052F401EF70F0708F3520F408
:10E64000E40DF51D708204C0E40DF51D8EE280839B
:10E650000894E11CF11C011D111D0894811C911CE2
:10E6600090E18916910409F0C2CF80E190E0A0E02A
:10E67000B0E0A80EB91ECA1EDB1E198AC2010F9493
:10E68000FAF10F94DCF16A94662009F072CF629679
:10E690000FB6F894DEBF0FBECDBFCF91DF911F91B3
:10E6A0000F91FF90EF90DF90CF90BF90AF909F9031
:10E6B0008F907F906F905F904F903F902F90089534
:10E6C0002F923F924F925F926F927F928F929F9282
:10E6D000AF92BF92CF92DF92EF92FF920F931F9370
:10E6E000DF93CF93CDB7DEB7CD53D1400FB6F894BB
:10E6F000DEBF0FBECDBF01E20EBF0FEF0DBF94B75F
:10E70000F894A89514BE80916000886180936000A1
:10E7100010926000789493FF05C0E0910002F091A0
:10E7200001021995279A2F9A8091C00082608093E8
:10E73000C00080E18093C40088E18093C1000000A4
:10E74000EE24FF24870144E0A42EB12CCC24DD2448
:10E7500024C0C5010197F1F70894E11CF11C011DCB
:10E76000111D21E2E2162EE4F20620E0020720E06D
:10E77000120718F031E0C32ED12CC801B70127ECE5
:10E780003BE140E050E00F9441FE611571058105C9
:10E79000910519F485B1805885B98091C00087FD35
:10E7A00003C0C114D104A9F2A6014F5F5F4FC25E3E
:10E7B000DE4F59834883CE51D140C25EDE4F8881FF
:10E7C0009981CE51D140019711F00D9410FEC05D9A
:10E7D000DE4F19821882C053D14060E0C15DDE4F28
:10E7E0001882CF52D14088249924C35DDE4F19820C
:10E7F0001882CD52D140C05EDE4F188219821A8233
:10E800001B82C052D140CE5CDE4F188219821A8220
:10E810001B82C253D140EE24FF2487010BBFF701B6
:10E8200007911691C45CDE4F19830883CC53D14005
:10E830000D940BFEC25EDE4F28813981CE51D1404E
:10E840002130310509F52091C600C25EDE4F1982E4
:10E850001882CE51D14022C02F5F3F4F4F4F5F4FA4
:10E86000213082E138078AE7480780E0580780F0C6
:10E87000C45CDE4FE881F981CC53D140EF5FFF4F9C
:10E8800019F0EE27FF27099420E030E040E050E047
:10E890008091C00087FFE0CF2091C600C35DDE4FAE
:10E8A00048815981CD52D1404F5F5F4FC35DDE4FEC
:10E8B00059834883CD52D140213209F063C64A3092
:10E8C000510508F05FC60894811C911C53E0851621
:10E8D000910409F059C600E010E018C081E280936D
:10E8E000C6008091C00086FFFCCF8091C00080648C
:10E8F0008093C0002F5F3F4F2931310579F70F9486
:10E90000DCF10F5F1F4F0530110519F020E030E0FA
:10E91000E5CF10920A0210920B0210920C02109294
:10E920000D02109206021092070210920802109235
:10E930000902109202021092030210920402109235
:10E9400005028FEE90EE60E00F94F5F180E191EE1C
:10E9500060E00F94C2F18091C00087FFFCCF9091DE
:10E96000C600903608F09F759032B8F09093C600BC
:10E970008091C00086FFFCCF8091C00080648093AE
:10E98000C000A0E2A093C6008091C00086FFFCCF2B
:10E990008091C00080648093C000983409F4D7C18E
:10E9A0009934B8F4923409F459C1933458F490333B
:10E9B00019F1903308F4E3C59F33A1F1903409F0C5
:10E9C000DEC5BDC0953409F470C1963409F0D7C5D1
:10E9D00098C1923509F42BC2933538F49C3409F46C
:10E9E000F5C1913509F0CBC518C2963509F445C279
:10E9F000993509F0C4C567C483E792EE62E00F94CD
:10EA0000F5F110920602109207021092080210927D
:10EA1000090210920A0210920B0210920C0210923C
:10EA20000D0213C18FE792EE62E00F94F5F18FEEC5
:10EA300090EE60E00F94F5F181E291EE60E00F94CA
:10EA4000C2F187EB91EE60E00F94F5F180E391EE77
:10EA500060E00F94C2F184EE90EE60E00F94F5F167
:10EA60008FE391EE60E00F94C2F186E090E061E008
:10EA700070E00F9434F20F94DCF18DE591EE60E0DC
:10EA80000F94C2F189EC91EE60E00F94F5F18EE401
:10EA900091EE60E00F94C2F183EC91EE60E00F9490
:10EAA000F5F18CE691EE60E00F94C2F18EE10F94E7
:10EAB0000DF288E90F940DF281E00F940DF20F949E
:10EAC000DCF18BE791EE60E00F94C2F119E0E0E039
:10EAD000F0E010935700E4918E2F0F940DF20F94F5
:10EAE000DCF18AE891EE60E00F94C2F1E3E0F0E03F
:10EAF00010935700E4918E2F0F940DF20F94DCF1D8
:10EB000089E991EE60E00F94C2F1E2E0F0E0109349
:10EB10005700E4918E2F0F940DF20F94DCF188EAE8
:10EB200091EE60E00F94C2F1E1E0F0E01093570045
:10EB30001491812F0F940DF20F94DCF107CF8BE825
:10EB400092EE62E00F94F5F18BE492EE60E00F94A8
:10EB5000F5F10F94DCF100E010E019C0C8016F2D51
:10EB60000F947FFEFF2031F489E492EE60E00F9471
:10EB7000C2F10BC0F092C6008091C00086FFFCCFAE
:10EB80008091C00080648093C0000F5F1F4FC80158
:10EB900081519F41A0E0B0E0ABBFFC01F790BAE229
:10EBA000FB1621F0E2E000301E07C1F60F94DCF105
:10EBB0000F94DCF187E592EE60E00F94F5F10F948D
:10EBC000DCF1CC24DD2400E010E01EC0C8010F946D
:10EBD00077FEF82E882331F489E492EE60E00F94FA
:10EBE000C2F10BC08093C6008091C00086FFFCCFAD
:10EBF0008091C00080648093C000FE1419F00894D6
:10EC0000C11CD11C0F5F1F4FC80181519F41A0E063
:10EC1000B0E0ABBFFC01E790FAE2EF1621F022E092
:10EC20000030120799F60F94DCF10F94DCF182E6C4
:10EC300092EE60E00F94C2F1C60161E070E00F94C3
:10EC400034F20F94DCF10F94DCF110920202109276
:10EC50000302109204021092050278CE89E992EE26
:10EC600062E00F94F5F1279A2F9A16C02F9880E052
:10EC700090E0E0EDF7E03197F1F7019684369105E9
:10EC8000C1F72F9A80E090E0E0EDF7E03197F1F7DF
:10EC9000019684369105C1F78091C00087FFE6CFC9
:10ECA0008091C00087FFFCCF64C485EA92EE62E0E9
:10ECB0000F94F5F140910202509103026091040219
:10ECC0007091050281E020E10F9491F2809102029F
:10ECD00090910302A0910402B091050280509F4FD1
:10ECE000AF4FBF4F8093020290930302A0930402A0
:10ECF000B093050280509041A040B04008F426CE69
:10ED0000A4CF83EB92EE62E00F94F5F140910602FE
:10ED100050910702609108027091090280E020E1A1
:10ED20000F9491F28091060290910702A09108023F
:10ED3000B091090280509F4FAF4FBF4F80930602A2
:10ED400090930702A0930802B0930902FFCD80ECD4
:10ED500092EE62E00F94F5F183E792EE60E00F949B
:10ED6000F5F18FE792EE60E00F94F5F18BE892EE0B
:10ED700060E00F94F5F189E992EE60E00F94F5F10F
:10ED800085EA92EE60E00F94F5F183EB92EE60E09D
:10ED90000F94F5F180EC92EE60E00F94F5F187ECC2
:10EDA00092EE60E00F94F5F188ED92EE60E00F9442
:10EDB000F5F18FED92EE60E00F94F5F18AEE92EEB0
:10EDC00060E00F94F5F183E093EEBDCD87EC92EE19
:10EDD00062E00F94F5F181E40F947BF282E40F94EA
:10EDE0007BF283E40F947BF284E40F947BF285E45E
:10EDF0000F947BF286E40F947BF287E40F947BF20E
:10EE000088E40F947BF28AE40F947BF28BE40F94F6
:10EE10007BF28CE40F947BF299CD88ED92EE62E068
:10EE20000F94F5F1772473948824992409C48FED05
:10EE300092EE62E00F94F5F140910A0250910B02BC
:10EE400060910C0270910D0282E020E10F9491F22A
:10EE500080910A0290910B02A0910C02B0910D02D8
:10EE600080509F4FAF4FBF4F80930A0290930B0289
:10EE7000A0930C02B0930D0269CD8AEE92EE62E08F
:10EE80000F94F5F184EE90EE60E00F94F5F18FECC5
:10EE900091EE60E00F94F5F1662477244301CC5D98
:10EEA000DE4F19821882C452D140D401C301B695F5
:10EEB000A79597958795CA5DDE4F88839983AA8326
:10EEC000BB83C652D140CC5DDE4FA881B981C4520C
:10EED000D1401196CC5DDE4FB983A883C452D14096
:10EEE000CD0162E070E00F9434F2B0E2B093C6005E
:10EEF0008091C00086FFFCCF8091C0008064809329
:10EF0000C000EDE2E093C6008091C00086FFFCCF18
:10EF10008091C00080648093C000F0E2F093C6004E
:10EF20008091C00086FFFCCF8091C00080648093F8
:10EF3000C000CA5DDE4FE880F9800A811B81C6529D
:10EF4000D140BB27A12F902F8F2D0F940DF2CA5DBA
:10EF5000DE4F8881C652D1400F940DF2B0E2FB2EF5
:10EF6000F092C6008091C00086FFFCCF8091C00067
:10EF700080648093C0000DE30093C6008091C000C0
:10EF800086FFFCCF8091C00080648093C00010E2B7
:10EF90001093C6008091C00086FFFCCF8091C00016
:10EFA00080648093C0008BBEF3012791C65DDE4F65
:10EFB0002883CA52D140A22EBB24CC24DD2408943D
:10EFC000611C711C811C911C8BBEF3018791282E42
:10EFD0003324442455240894611C711C811C911C09
:10EFE0008BBEF3013791C55DDE4F3883CB52D140E4
:10EFF0000894611C711C811C911C8BBEF30147910C
:10F00000C45DDE4F4883CC52D140ADEFEA2EAFEF66
:10F01000FA2EAFEF0A2FAFEF1A2F6E0C7F1C801E57
:10F02000911E142D032DF22CEE24EA0CFB1C0C1D5A
:10F030001D1D0F940DF220E22093C6008091C000A8
:10F0400086FFFCCF8091C00080648093C000C65DC5
:10F05000DE4F8881CA52D1400F940DF230E23093D6
:10F06000C6008091C00086FFFCCF8091C000806404
:10F070008093C000C45DDE4F8881CC52D1400F9494
:10F080000DF240E24093C6008091C00086FFFCCFA5
:10F090008091C00080648093C000C55DDE4F888190
:10F0A000CB52D1400F940DF250E25093C6008091A4
:10F0B000C00086FFFCCF8091C00080648093C000B8
:10F0C0008FEFE8168FEFF80680E0080780E018075A
:10F0D00031F484E092EE60E00F94C2F1DFC0D80119
:10F0E000C7018070907CA070B0708050904CA040A0
:10F0F000B040D1F52FEF3FE340E050E0E222F322B1
:10F1000004231523CA5DDE4FA880B980CA80DB8046
:10F11000C652D140AE0CBF1CC01ED11EAA0CBB1CD7
:10F12000CC1CDD1C8EE092EE60E00F94C2F1BB2798
:10F13000A12F902F8F2D0F940DF28E2D0F940DF285
:10F1400030E23093C6008091C00086FFFCCF8091F2
:10F15000C00080648093C0004EE34093C60080915D
:10F16000C00086FFFCCF87C08EE09EEFA0E0B0E03D
:10F17000E822F9220A231B239CE0E91694E9F90608
:10F1800090E0090790E0190709F088C0C45DDE4FE0
:10F19000A881CC52D140EA2EFF2400E010E0102FCD
:10F1A0000F2DFE2CEE24C55DDE4FB881CB52D14031
:10F1B000EB0EF11C011D111DD601C501817090706F
:10F1C000A070B070DC0199278827E80EF91E0A1F8D
:10F1D0001B1F20EF30E040E050E0A222B322C42207
:10F1E000D52241E1AA0CBB1CCC1CDD1C4A95D1F7F1
:10F1F000EA0CFB1C0C1D1D1D81E090E0A0E0B0E0BE
:10F20000282239224A225B2235E1220C331C441C7D
:10F21000551C3A95D1F7E20CF31C041D151D57013E
:10F220006801AA0CBB1CCC1CDD1C85E192EE60E0E1
:10F230000F94C2F1C801AA27BB270F940DF2BB2778
:10F24000A12F902F8F2D0F940DF28E2D0F940DF274
:10F2500090E29093C6008091C00086FFFCCF809121
:10F26000C00080648093C000AEE3A093C60080918C
:10F27000C00086FFFCCF8091C00080648093C000F6
:10F28000C601AA27BB270F940DF2BB27AD2D9C2DDD
:10F290008B2D0F940DF28A2D0F940DF20F94DCF14B
:10F2A000CC5DDE4FE881F981C452D140F99709F471
:10F2B0004DCBF4E0EF2EF12C012D112D6E0C7F1CA7
:10F2C000801E911EF2CD83E093EE62E00F94F5F183
:10F2D0008AE192EE60E00F94C2F18091C00087FF56
:10F2E000FCCF1091C6001F751093C6008091C0001E
:10F2F00086FFFCCF8091C00080648093C0000F9493
:10F30000DCF1812F81548A3108F036C1163409F4BA
:10F3100095C0173490F4133409F44EC0143430F40B
:10F320001134F1F0123409F01DC130C0143409F465
:10F3300059C0153409F016C16BC01A3409F4C4C0A1
:10F340001B3438F4173409F48FC0183409F00AC19B
:10F35000A1C01B3409F4D2C01C3409F003C1E8C0B9
:10F360008FEF81B90DC082B1809582B980E090E0C5
:10F37000E0EDF7E03197F1F70196883C9105C1F790
:10F380008091C00087FFEFCF12B8EFC08FEF84B934
:10F390000DC085B1809585B980E090E0E0EDF7E0A3
:10F3A0003197F1F70196883C9105C1F78091C00033
:10F3B00087FFEFCF15B8D9C08FEF87B90DC088B1DF
:10F3C000809588B980E090E0E0EDF7E03197F1F7C3
:10F3D0000196883C9105C1F78091C00087FFEFCF6F
:10F3E00018B8C3C08FEF8AB90DC08BB180958BB9A7
:10F3F00080E090E0E0EDF7E03197F1F70196883C8E
:10F400009105C1F78091C00087FFEFCF1BB8ADC059
:10F410008FEF8DB90DC08EB180958EB980E090E0F0
:10F42000E0EDF7E03197F1F70196883C9105C1F7DF
:10F430008091C00087FFEFCF1EB897C08FEF80BBD1
:10F440000DC081B3809581BB80E090E0E0EDF7E0F6
:10F450003197F1F70196883C9105C1F78091C00082
:10F4600087FFEFCF11BA81C08FEF83BB0DC084B38C
:10F47000809584BB80E090E0E0EDF7E03197F1F714
:10F480000196883C9105C1F78091C00087FFEFCFBE
:10F4900014BA6BC08FEF809301010FC080910201FD
:10F4A00080958093020180E090E0E0EDF7E03197F5
:10F4B000F1F70196883C9105C1F78091C00087FF64
:10F4C000EDCF1092020151C08FEF809304010FC065
:10F4D0008091050180958093050180E090E0E0ED4A
:10F4E000F7E03197F1F70196883C9105C1F78091DB
:10F4F000C00087FFEDCF1092050137C08FEF8093DA
:10F5000007010FC08091080180958093080180E079
:10F5100090E0E0EDF7E03197F1F70196883C910536
:10F52000C1F78091C00087FFEDCF109208011DC088
:10F530008FEF80930A010FC080910B01809580931B
:10F540000B0180E090E0E0EDF7E03197F1F70196F4
:10F55000883C9105C1F78091C00087FFEDCF1092E4
:10F560000B0103C085E292EEEEC98091C00087FFD7
:10F57000FCCF8091C600EAC988E392EEE4C98CE131
:10F5800091EEE1C988249924933011F1943028F444
:10F59000913089F09230B8F408C0953061F195301F
:10F5A000F0F0963009F048C043C02B3109F042C951
:10F5B00091E06BE13FC96227C15DDE4F2883CF52E6
:10F5C000D14092E037C9B22FA0E0622793E032C960
:10F5D000822F90E0A82BB92B622794E02BC92E3004
:10F5E00009F039C3622795E0C05DDE4F19821882A9
:10F5F000C053D1401FC9E1E0F0E0EC0FFD1FC05D3A
:10F60000DE4F08811981C053D140E00FF11F2083E4
:10F610000F5F1F4FC05DDE4F19830883C053D14079
:10F6200062270A171B0709F005C9D80196E002C92D
:10F63000261709F010C303C0973009F0FBC87724E0
:10F640009981933109F412C19431C8F4963009F4C8
:10F65000D8C0973050F4923009F406C1933009F4C1
:10F660006DC0913009F059C253C0913109F477C08F
:10F67000923108F0BBC0903109F04FC2F5C098310B
:10F6800009F487C0993150F4953109F4EFC09531F0
:10F6900008F4C6C1963109F040C2C2C19A3109F4DA
:10F6A0006CC09A3108F491C09B3109F45BC09D3164
:10F6B00009F033C29D81903359F48F81882311F46E
:10F6C0009EE11CC0813011F091E018C098E916C08D
:10F6D000892F807591F0903539F4E0E0F0E089E011
:10F6E0008093570094910AC0983539F4E3E0F0E034
:10F6F00089E080935700949101C090E01A821B82A8
:10F700008D818C831D829E831F8227E030E009C299
:10F710001A8288E08B8381E48C8386E58D8382E581
:10F720008E8389E48F8383E5888780E589878FE5E9
:10F730008A8782E38B872BE030E0F3C18A818139AD
:10F7400041F0823941F0803911F48FE005C080E04A
:10F7500003C082E001C08AE01A828B8344C0772410
:10F76000739482C08D81882311F48EE12CC0813086
:10F7700011F081E028C088E926C01A82E1E0F0E0BB
:10F7800089E08093570084918B831C8224E030E0D1
:10F79000C8C18B81803589F48C81883039F4E2E0EE
:10F7A000F0E089E08093570084910DC0E0E0F0E044
:10F7B00089E080935700849106C0E3E0F0E089E09F
:10F7C0008093570084911A82DFCF8D81836C99E0FA
:10F7D000E1E0F0E0082E90935700E89507B600FCB2
:10F7E000FDCF1A821B8223E030E09BC180EC8A832C
:10F7F000CE5CDE4F188219821A821B82C253D1401E
:10F800008EC18A8190E0A0E0B0E0582F44273327D2
:10F8100022278B8190E0A0E0B0E0DC0199278827C7
:10F82000282B392B4A2B5B2B8D8190E0A0E0B0E098
:10F83000282B392B4A2B5B2B8C8190E0A0E0B0E089
:10F84000BA2FA92F982F8827282B392B4A2B5B2BCF
:10F85000220F331F441F551FC05EDE4F288339839C
:10F860004A835B83C052D1401A8259C13A81C95C34
:10F87000DE4F3883C753D140CA5CDE4F1882C6536F
:10F88000D1408B81C82EDD24CA5CDE4F488159816E
:10F89000C653D140C42AD52A933109F082C0CE5C28
:10F8A000DE4F88819981AA81BB81C253D1408050AB
:10F8B000904CA340B04030F583E0CE5CDE4FE88052
:10F8C000F9800A811B81C253D140F70100935B008C
:10F8D00080935700E89507B600FCFDCFCE5CDE4F65
:10F8E000088119812A813B81C253D14000501F4FAA
:10F8F0002F4F3F4FCE5CDE4F088319832A833B8313
:10F90000C253D140C05EDE4F488159816A817B81FC
:10F91000C052D140DE011B9631E08C9111962C91A2
:10F9200011971296C75CDE4F2883C953D140C85C3B
:10F93000DE4F1882C853D14090E0C85CDE4FE881AA
:10F94000F981C853D1408E2B9F2B0C01FA01609393
:10F950005B0030935700E89511244E5F5F4F6F4F67
:10F960007F4F0EEFE02E0FEFF02ECE0CDF1CC114F8
:10F97000D10499F685E0C05EDE4F088119812A81A5
:10F980003B81C052D140F80120935B008093570027
:10F99000E89507B600FCFDCF81E180935700E8951C
:10F9A00035C0C05EDE4F88819981AA81BB81C0527B
:10F9B000D140B695A795979587957C018601ABE0D8
:10F9C000AA2EB12CAC0EBD1E0BC0D5016D915D01F0
:10F9D000C7010F947FFE0894E11CF11C01501040F8
:10F9E0000115110591F7A60160E070E0440F551F65
:10F9F000661F771FC05EDE4FE880F9800A811B8199
:10FA0000C052D1404E0D5F1D601F711F1A82C05E33
:10FA1000DE4F488359836A837B83C052D1407FC0C5
:10FA2000FA80C55CDE4FF882CB53D140C65CDE4F16
:10FA30001882CA53D1408B81C82EDD24C65CDE4FAC
:10FA400008811981CA53D140C02AD12A1A828981DA
:10FA5000BE016D5F7F4F843121F59601C05EDE4FA0
:10FA6000E880F9800A811B81C052D1400BBFF701A9
:10FA700087919691DB018C9311969C936E5F7F4FDB
:10FA8000D801C7010296A11DB11DC05EDE4F88835B
:10FA90009983AA83BB83C052D14022503040F1F6F3
:10FAA00036C0C05EDE4F288139814A815B81C052F9
:10FAB000D1400894C108D108760100E010E0089414
:10FAC000C11CD11C0894E11CF11C011D111DE20E8A
:10FAD000F31E041F151F21BDBB27A52F942F832FB5
:10FAE00082BD2F5F3F4F4F4F5F4FF89A80B5DB01CC
:10FAF0008D93BD012E153F054007510761F7C05E8C
:10FB0000DE4F288339834A835B83C052D1409601FC
:10FB10002D5F3F4FFB01108204C080EC8A8322E0FE
:10FB200030E08BE18093C6008091C00086FFFCCF5F
:10FB30008091C00080648093C000C15DDE4FF88179
:10FB4000CF52D140F093C6008091C00086FFFCCF19
:10FB50008091C00080648093C000432F3093C60022
:10FB60008091C00086FFFCCF8091C00080648093AC
:10FB7000C000922F2093C6008091C00086FFFCCF6A
:10FB80008091C00080648093C0008EE08093C600A6
:10FB90008091C00086FFFCCF8091C000806480937C
:10FBA000C00065E1C15DDE4FE880CF52D1406E25D7
:10FBB00069276427FE01319610C090819093C6009A
:10FBC0008091C00086FFFCCF31968091C000806498
:10FBD0008093C0006927215030402115310569F715
:10FBE0006093C6008091C00086FFFCCF8091C0006A
:10FBF00080648093C00085B1805885B9772081F4F6
:10FC0000C15DDE4F0881CF52D1400F5FC15DDE4F35
:10FC10000883CF52D14090E0A0E0B0E00D941AF4F8
:10FC200027982F9880E090E020ED37E0F901319798
:10FC3000F1F7019684369105C9F700008091C00064
:10FC40008D7F8093C00081E180935700E895EE2777
:10FC5000FF270994FFCF90E00D941AF497FB092E2B
:10FC600007260AD077FD04D02ED006D000201AF443
:10FC7000709561957F4F0895F6F7909581959F4F08
:10FC80000895A1E21A2EAA1BBB1BFD010DC0AA1FDD
:10FC9000BB1FEE1FFF1FA217B307E407F50720F0F5
:10FCA000A21BB30BE40BF50B661F771F881F991F70
:10FCB0001A9469F760957095809590959B01AC01B9
:10FCC000BD01CF010895AA1BBB1B51E107C0AA1FAC
:10FCD000BB1FA617B70710F0A61BB70B881F991FED
:10FCE0005A95A9F780959095BC01CD010895F99991
:10FCF000FECF92BD81BDF89A992780B50895262F31
:10FD0000F999FECF1FBA92BD81BD20BD0FB6F89400
:0EFD1000FA9AF99A0FBE01960895F894FFCF63
:040000033000E000E9
:00000001FF

120
utility/bluetooth/bluesmirf-rn42/bluesmirf-rn42.ino Executable file → Normal file
View File

@ -1,56 +1,64 @@
/* /*Author: EmaMaker (emamaker.altervista.org) on 8/3/2020
Example Bluetooth Serial Passthrough Sketch Write and read data from two bluesmirf rn-42 at the same time*/
by: Jim Lindblom #include <SoftwareSerial.h>
SparkFun Electronics
date: February 26, 2013 int bluetoothTx = 2; // TX-O pin of bluetooth mate, Arduino D2
license: Public domain int bluetoothRx = 3; // RX-I pin of bluetooth mate, Arduino D3
This example sketch converts an RN-42 bluetooth module to //SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
communicate at 9600 bps (from 115200), and passes any serial #define bluetooth1 Serial3
data between Serial Monitor and bluetooth module. #define bluetooth2 Serial2
*/
#include <SoftwareSerial.h> HardwareSerial* current= nullptr;
int bluetoothTx = 2; // TX-O pin of bluetooth mate, Arduino D2 char a = ' ';
int bluetoothRx = 3; // RX-I pin of bluetooth mate, Arduino D3
void setup() {
//SoftwareSerial bluetooth(bluetoothTx, bluetoothRx); Serial.begin(9600); // Begin the serial monitor at 9600bps
<<<<<<< HEAD bluetooth1.begin(19200);
======= bluetooth2.begin(19200);
}
#define bluetooth Serial3
>>>>>>> 5c0171dd181357ae6f20ec98cb5c060f067c30fc void read(HardwareSerial* bluetooth) {
while (bluetooth->available()) {
#define bluetooth Serial3 if(bluetooth == &bluetooth1){
Serial.print("Bluetooth1 Read: ");
void setup() { }else if(bluetooth == &bluetooth2){
Serial.begin(9600); // Begin the serial monitor at 9600bps Serial.print("Bluetooth2 Read: ");
<<<<<<< HEAD }
// Send any characters the bluetooth prints to the serial monitor
bluetooth.begin(9600); // Start bluetooth serial at 9600 Serial.println((char)bluetooth->read());
======= delay(50);
bluetooth.begin(9600); }
>>>>>>> 5c0171dd181357ae6f20ec98cb5c060f067c30fc }
}
void write(HardwareSerial* bluetooth) {
void read() { if(a != ' ') {
while (bluetooth.available()) { if(bluetooth == &bluetooth1){
// Send any characters the bluetooth prints to the serial monitor Serial.print("Bluetooth1 Write: ");
Serial.print((char)bluetooth.read()); }else if(bluetooth == &bluetooth2){
delay(50); Serial.print("Bluetooth2 Write: ");
} }
} // Send any characters the Serial monitor prints to the bluetooth
Serial.println(a);
void write() { bluetooth->print(a);
while (Serial.available()) { a = ' ';
// Send any characters the Serial monitor prints to the bluetooth }
bluetooth.print((char)Serial.read()); }
delay(50);
} bool b = false;
// and loop forever and ever! void loop() {
} b = !b;
void loop() { while(Serial.available() > 0){
read(); a = (char)Serial.read();
write(); if(a == '-') current = &bluetooth1;
} else if(a == '_') current = &bluetooth2;
if(a == '-' || a == '_') a = ' ';
}
if(current != nullptr) write(current);
read(&bluetooth1);
read(&bluetooth2);
}

120
utility/bluetooth/bluesmirf-rn42_2/bluesmirf-rn42_2.ino Executable file → Normal file
View File

@ -1,68 +1,52 @@
/* /*Use this script to reprogram the bluesmirf-rn42 using an arduino microcontroller.
Example Bluetooth Serial Passthrough Sketch Bluesmirf defaults the uart speed to 115200 after factory reset, so a SoftwareSerial may not be ideal for a long use, but it can be used to enter command mode and temp-change the uart speed to 9600 using the SU,9600 command
by: Jim Lindblom First of all it may be useful to reset the BT module to its factory settings, a useful video on how to do it can be found here: https://www.youtube.com/watch?v=8gZNF3bFpzI
SparkFun Electronics Upload a Blink program to the arduino, when the pin is high give power to the module, an instant short-flashing on the status led followed by a couple of seconds of the led being off means that the module has been reset
date: February 26, 2013 Now you can connect with this script and setup the BT module:
license: Public domain Enter command mode sending $$ no line ending in serial
Give the following commands to setup the bluesmirf as intended for our use
This example sketch converts an RN-42 bluetooth module to Read the manual for further information about the commands used
communicate at 9600 bps (from 115200), and passes any serial SM,2 Trigger mode
data between Serial Monitor and bluetooth module. SA,0 No authentication needed
*/ SU,19200 Baud rate to 19200
#include <SoftwareSerial.h> SR, address The address the module has to connect to
ST, number Amount of time (in seconds) of inactivity after which the connection is terminated (1 is too low, 3 is used during the tests, 2 should to the thing)
int bluetoothTx = 2; // TX-O pin of bluetooth mate, Arduino D2
int bluetoothRx = 3; // RX-I pin of bluetooth mate, Arduino D3 When trying to connect one bluetooth module with another one, please make sure that the two are powered off with at least 300mS of difference: if they are trying to connect with each other at the same moment, the connection will fail
*/
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
#include <SoftwareSerial.h>
void setup()
{ int bluetoothTx = 2; // TX-O pin of bluetooth mate, Arduino D2
Serial.begin(9600); // Begin the serial monitor at 9600bps int bluetoothRx = 3; // RX-I pin of bluetooth mate, Arduino D3
/*bluetooth.begin(115200); // The Bluetooth Mate defaults to 115200bps //SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
bluetooth.print("$"); // Print three times individually #define bluetooth Serial3
bluetooth.print("$");
bluetooth.print("$"); // Enter command mode void setup() {
delay(100); // Short delay, wait for the Mate to send back CMD Serial.begin(9600); // Begin the serial monitor at 9600bps
bluetooth.println("U,9600,N"); // Temporarily Change the baudrate to 9600, no parity delay(1000);
//115200 can be too fast at times for NewSoftSerial to relay the data reliably*/ bluetooth.begin(19200);
}
delay(1000);
void read() {
bluetooth.begin(9600); // Start bluetooth serial at 9600 while (bluetooth.available()) {
bluetooth.print("$"); // Print three times individually // Send any characters the bluetooth pri$$$nts to the serial monitor
bluetooth.print("$"); Serial.print((char)bluetooth.read());
bluetooth.print("$"); }
read(); }
delay(1000);
bluetooth.println("SA,0"); void write() {
read(); while (Serial.available()) {
bluetooth.println("SM,6"); // Send any characters the Serial monitor prints to the bluetooth
read(); char a = (char)Serial.read();
delay(1000); bluetooth.print(a);
bluetooth.println("C"); Serial.print(a);
read(); }
} // and loop forever and ever!
}
void read() {
while (bluetooth.available()) { void loop() {
// Send any characters the bluetooth prints to the serial monitor read();
Serial.print((char)bluetooth.read()); write();
delay(50); }
}
}
void write() {
while (Serial.available()) {
// Send any characters the Serial monitor prints to the bluetooth
bluetooth.print((char)Serial.read());
delay(50);
}
// and loop forever and ever!
}
void loop() {
bluetooth.write(42);
delay(500);
}