@tigerpython/robotics-libraries 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +68 -0
- package/LICENSE +373 -0
- package/README.md +81 -0
- package/calliope/README.md +15 -0
- package/calliope/callibot.py +176 -0
- package/calliope/callibotmot.py +46 -0
- package/calliope/callimk.py +143 -0
- package/calliope/cbalarm.py +14 -0
- package/calliope/cpglow.py +76 -0
- package/calliope/cpmike.py +16 -0
- package/calliope/cprover.py +33 -0
- package/calliope/cputils.py +23 -0
- package/calliope/libraries.json +10 -0
- package/calliope/libraries.raw.json +10 -0
- package/calliope/min/callibot.py +97 -0
- package/calliope/min/callibotmot.py +23 -0
- package/calliope/min/callimk.py +47 -0
- package/calliope/min/cbalarm.py +6 -0
- package/calliope/min/cpglow.py +29 -0
- package/calliope/min/cpmike.py +8 -0
- package/calliope/min/cprover.py +9 -0
- package/calliope/min/cputils.py +7 -0
- package/dist/index.d.mts +124 -0
- package/dist/index.d.ts +124 -0
- package/dist/index.js +2896 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2862 -0
- package/dist/index.mjs.map +1 -0
- package/microbit/README.md +48 -0
- package/microbit/controller.py +212 -0
- package/microbit/huskylens.py +479 -0
- package/microbit/libraries.json +19 -0
- package/microbit/libraries.raw.json +19 -0
- package/microbit/mbalarm.py +15 -0
- package/microbit/mbbitbot.py +127 -0
- package/microbit/mbglow.py +77 -0
- package/microbit/mbled.py +56 -0
- package/microbit/mbmarsrover.py +216 -0
- package/microbit/mbminibit.py +139 -0
- package/microbit/mbrobot.py +401 -0
- package/microbit/mbrobot_legacy.py +90 -0
- package/microbit/mbrobot_plus.py +179 -0
- package/microbit/mbrobot_plusV2.py +490 -0
- package/microbit/mbrobot_plusV3.py +427 -0
- package/microbit/mbrobotmot.py +49 -0
- package/microbit/mbthetabot.py +167 -0
- package/microbit/mbwait.py +50 -0
- package/microbit/mbxgo.py +173 -0
- package/microbit/min/controller.py +42 -0
- package/microbit/min/huskylens.py +145 -0
- package/microbit/min/mbalarm.py +6 -0
- package/microbit/min/mbbitbot.py +40 -0
- package/microbit/min/mbglow.py +29 -0
- package/microbit/min/mbled.py +18 -0
- package/microbit/min/mbmarsrover.py +62 -0
- package/microbit/min/mbminibit.py +50 -0
- package/microbit/min/mbrobot.py +82 -0
- package/microbit/min/mbrobot_legacy.py +45 -0
- package/microbit/min/mbrobot_plus.py +75 -0
- package/microbit/min/mbrobot_plusV2.py +102 -0
- package/microbit/min/mbrobot_plusV3.py +194 -0
- package/microbit/min/mbrobotmot.py +25 -0
- package/microbit/min/mbthetabot.py +47 -0
- package/microbit/min/mbwait.py +23 -0
- package/microbit/min/mbxgo.py +37 -0
- package/package.json +54 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"huskylens": "_E='Invalid model_id. Must be number in range [0,4]'\n_D='Error: ID must be in range from 1 to 255.'\n_C=None\n_B=True\n_A=False\nfrom microbit import i2c,sleep,running_time\nimport math\n_g1=['FaceRecognition','ObjectTracking','ObjectRecognition','LineTracking','ColorRecognition','TagRecognition','ObjectClassification','QRRecognition','BarcodeRecognition']\nclass Request_Command:KNOCK=44;ALGORITHM=45;ALL=32;BLOCKS=33;BLOCKS_LEARNED=36;BLOCKS_OF_ID=39;ARROWS=34;ARROWS_LEARNED=37;ARROWS_OF_ID=40;LEARNED=35;ALL_OF_ID=38;LEARN=54;FORGET=55;CUSTOM_LABEL=47;CUSTOM_TEXT=52;CLEAR_TEXT=53;SAVE_MODEL=50;LOAD_MODEL=51;SAVE_PHOTO=48;SAVE_SCREENSHOT=57;IS_PRO=59;VERSION=60\nclass Return_Code:ANY=1;OK=46;BUSY=61;INFO=41;BLOCK=42;ARROW=43;IS_PRO=59;NEED_PRO=62\nclass Algorithm:FACE_RECOGNITION=0;OBJECT_TRACKING=1;OBJECT_RECOGNITION=2;LINE_TRACKING=3;COLOR_RECOGNITION=4;TAG_RECOGNITION=5;OBJECT_CLASSIFICATION=6;QR_RECOGNITION=7;BARCODE_RECOGNITION=8\nclass Block:\n\tdef __init__(A,x,y,width,height,id):A.x=x;A.y=y;A.width=width;A.height=height;A.id=id\n\tdef _f2(A):return'Block: ID_'+str(A.id)+' Pos: ('+str(A.x)+' '+str(A.y)+') Size: ('+str(A.width)+' '+str(A.height)+')'\nclass Arrow:\n\tdef __init__(A,x_tail,y_tail,x_head,y_head,id):A.x_tail=x_tail;A.y_tail=y_tail;A.x_head=x_head;A.y_head=y_head;A.id=id\n\tdef get_direction(A):\n\t\tC=A.x_head-A.x_tail;D=A.y_head-A.y_tail;B=90-math.degrees(math.atan2(D,C))\n\t\tif B<0:B=B+360\n\t\treturn int(B)\n\tdef _f2(A):return'Arrow: ID_'+str(A.id)+' ('+str(A.x_tail)+' '+str(A.y_tail)+')->('+str(A.x_head)+' '+str(A.y_head)+')'\ndef byte_checksum(byte_list):return sum(byte_list)&255\ndef hexify(byte_array):\n\tA=byte_array\n\tif len(A)==0:return''\n\treturn'0x'+''.join('{:02x}'.format(A)for A in A)\nclass Huskylens:\n\tI2C_ADDR=50\n\tdef __init__(A):A.learned_slot_count=0;A.id_slots={};A.id_names={};A.algorithm=Algorithm.OBJECT_TRACKING;A.clear_texts();A.pro_enabled=A.is_pro()\n\tdef initialize(A):\n\t\tB=_A\n\t\tfor E in range(5):\n\t\t\tA.knock();B,F=A.get_response(Return_Code.OK)\n\t\t\tif B:break\n\t\tif B>0:\n\t\t\tC=A.clear_texts();D=A.set_algorithm(Algorithm.OBJECT_TRACKING)\n\t\t\tif C and D:print('Initialization successful!');return _B\n\t\t\telse:print(\"Initialization Failed. Couldn't change Algorithm\");return _A\n\t\telse:print('Initialization Failed. Please check connection to Huskylens.');return _A\n\tdef send_request(D,command,data=_C):\n\t\tB=data;A=bytearray(b'U\\xaa\\x11\\x00\\x00');A[3]=0 if B is _C else len(B);A[4]=command\n\t\tif B:\n\t\t\tfor C in B:A.append(C)\n\t\tA.append(byte_checksum(A));i2c.write(Huskylens.I2C_ADDR,A);sleep(50)\n\tdef get_response(K,return_code=Return_Code.ANY,timeout=500):\n\t\tC=return_code;A=bytearray(b'U\\x00\\x00\\x00\\x00');I=running_time()\n\t\twhile running_time()-I<timeout:\n\t\t\tD=i2c.read(Huskylens.I2C_ADDR,1)[0]\n\t\t\tif D==85:break\n\t\tif D!=85:return-1,[]\n\t\tfor J in range(4):A[J+1]=i2c.read(Huskylens.I2C_ADDR,1)[0]\n\t\tif A[0:3]!=b'U\\xaa\\x11':return-2,[]\n\t\tE=A[3];F=A[4];B=[]\n\t\tif E>0:G=i2c.read(Huskylens.I2C_ADDR,E+1);B=G[0:-1];H=G[-1]\n\t\telse:H=ord(i2c.read(Huskylens.I2C_ADDR,1))\n\t\tif H!=byte_checksum(list(A)+B):return-3,[]\n\t\tif C==Return_Code.ANY or F==C:return F,B\n\t\telse:return 0,B\n\tdef knock(A):A.send_request(Request_Command.KNOCK)\n\tdef set_algorithm(B,algorithm):\n\t\tA=algorithm\n\t\tif(A==Algorithm.QR_RECOGNITION or A==Algorithm.BARCODE_RECOGNITION)and not B.pro_enabled:raise RuntimeError('Error: Huskylens PRO version is required for algorithm ',_g1[A]);return _A\n\t\tD=[A,0];B.send_request(Request_Command.ALGORITHM,D);C,E=B.get_response(Return_Code.OK)\n\t\tif C>0:print('Current Algorithm:',_g1[A]);B.algorithm=A\n\t\treturn _B if C>0 else _A\n\tdef get_all(A):return A._f7(Request_Command.ALL)\n\tdef get_all_learned(A):return A._f7(Request_Command.LEARNED)\n\tdef get_all_with_id(A,id):\n\t\tif id<=0 or id>255:raise RuntimeError(_D)\n\t\treturn A._f7(Request_Command.ALL_OF_ID,id)\n\tdef get_one(A):B=A._f7(Request_Command.ALL);return A._f8(B)\n\tdef get_one_learned(A):B=A._f7(Request_Command.LEARNED);return A._f8(B)\n\tdef get_one_with_id(A,id):\n\t\tif id<=0 or id>255:raise RuntimeError(_D)\n\t\tB=A._f7(Request_Command.ALL_OF_ID,id);return A._f8(B)\n\tdef attach_label(A,id,name):\n\t\tB=name\n\t\tif A.algorithm==Algorithm.OBJECT_TRACKING or A.algorithm==Algorithm.LINE_TRACKING:C=A._f6(1,B)\n\t\telif A.algorithm==Algorithm.FACE_RECOGNITION or A.algorithm==Algorithm.TAG_RECOGNITION or A.algorithm==Algorithm.OBJECT_CLASSIFICATION or A.algorithm==Algorithm.OBJECT_RECOGNITION:\n\t\t\tD=A.id_slots.get(id)\n\t\t\tif D==_C:raise RuntimeError(\"Can't attach a name to an unlearned ID number\")\n\t\t\tA.id_names[id]=B;C=_B\n\t\t\tfor E in D:F=A._f6(E,B);C=C and F>0\n\t\telse:A.id_names[id]=B;C=A._f6(id,B)\n\t\treturn _B if C>0 else _A\n\tdef clear_labels(A):\n\t\tA.id_names.clear()\n\t\tfor B in range(10):A._f6(B,'')\n\tdef add_text(E,text,position_x,position_y):\n\t\tC=position_y;B=position_x;D=bytes(text,'utf-8')\n\t\tif len(D)>19:raise RuntimeError('Custom Text must be less than 20 bytes long.')\n\t\tif B>300 or B<0 or C<35 or C>240:raise RuntimeError(\"Custom Text can't be placed outside of screen pixel size.\")\n\t\tA=[len(D)];A.append(255 if B>255 else 0);A.append(B%255);A.append(240-C);A.extend(list(D));E.send_request(Request_Command.CUSTOM_TEXT,A);F,G=E.get_response(Return_Code.OK);return _B if F>0 else _A\n\tdef clear_texts(A):A.send_request(Request_Command.CLEAR_TEXT);B,C=A.get_response(Return_Code.OK);return _B if B>0 else _A\n\tdef learn(A,id,name=_C):\n\t\tif id<=0 or id>255:raise RuntimeError('Parameter ID for learned item must be in range [0,255]')\n\t\tif A.algorithm==Algorithm.OBJECT_TRACKING or A.algorithm==Algorithm.LINE_TRACKING:id=1\n\t\tC=500\n\t\tif A.algorithm==Algorithm.OBJECT_CLASSIFICATION:C=1000\n\t\tA.send_request(Request_Command.LEARN,[id,0]);B,E=A.get_response(Return_Code.OK,C)\n\t\tif B>0:\n\t\t\tA.learned_slot_count+=1\n\t\t\tif not id in A.id_slots:A.id_slots[id]=[A.learned_slot_count]\n\t\t\telse:A.id_slots[id].append(A.learned_slot_count)\n\t\t\tD=A.id_names.get(id)\n\t\t\tif D!=_C:B=A.attach_label(A.learned_slot_count,D)\n\t\t\telif name!=_C:B=A.attach_label(id,name)\n\t\treturn _B if B>0 else _A\n\tdef forget(A):\n\t\tA.send_request(Request_Command.FORGET);B,C=A.get_response(Return_Code.OK)\n\t\tif B:A.learned_slot_count=0;A.id_slots.clear()\n\t\treturn _B if B else _A\n\tdef save_photo(A):A.send_request(Request_Command.SAVE_PHOTO);B,C=A.get_response(Return_Code.OK,1000);return _B if B>0 else _A\n\tdef save_screenshot(A):A.send_request(Request_Command.SAVE_SCREENSHOT);B,C=A.get_response(Return_Code.OK,1000);return _B if B>0 else _A\n\tdef save_model(B,model_id):\n\t\tA=model_id\n\t\tif A<0 or A>4:raise RuntimeError(_E)\n\t\tB.send_request(Request_Command.SAVE_MODEL,[A,0]);C,D=B.get_response(Return_Code.OK,1000);print('Model saving: Check Huskylens screen for Result!\\n\\tModel name:',_g1[B.algorithm]+'_Backup_'+str(A)+'.conf');return _B if C>0 else _A\n\tdef load_model(B,model_id):\n\t\tA=model_id\n\t\tif A<0 or A>4:raise RuntimeError(_E)\n\t\tB.send_request(Request_Command.LOAD_MODEL,[A,0]);C,D=B.get_response(Return_Code.OK,1000);print('Model Loading: Check Huskylens screen for Result!');return _B if C>0 else _A\n\tdef is_pro(A):A.send_request(Request_Command.IS_PRO);B,C=A.get_response(Return_Code.IS_PRO);return bool(C[0])if B>0 else _A\n\tdef _f6(C,id,name):\n\t\tA=bytes(name,'utf-8')\n\t\tif len(A)>19:raise RuntimeError('Custom Name must be less than 20 bytes long.')\n\t\tB=[id,len(A)+1];B.extend(list(A));B.append(0);C.send_request(Request_Command.CUSTOM_LABEL,B);D,E=C.get_response(Return_Code.OK);return _B if D>0 else _A\n\tdef _f7(B,request_command,id=-1):\n\t\tI=_C if id<0 else[id,0];B.send_request(request_command,I);G,H=B.get_response(Return_Code.INFO)\n\t\tif not G:raise RuntimeError('Failed to request results. Got answer:'+str(G))\n\t\tJ=H[0]+H[1]*255;C=0;D=[]\n\t\twhile C<J:\n\t\t\tE,A=B.get_response(Return_Code.ANY)\n\t\t\tif E==Return_Code.BLOCK and B.algorithm!=3:K=A[0]+A[1]*255;L=240-A[2]+A[3]*255;M=A[4]+A[5]*255;N=A[6]+A[7]*255;F=A[8];O=Block(K,L,M,N,F);D.append(O);C+=1\n\t\t\telif E==Return_Code.ARROW:P=A[0]+A[1]*255;Q=240-A[2]+A[3]*255;R=A[4]+A[5]*255;S=240-A[6]+A[7]*255;F=A[8];T=Arrow(P,Q,R,S,F);D.append(T);C+=1\n\t\t\telif E==0:return[]\n\t\treturn D\n\tdef _f8(E,results):\n\t\tC=_C;D=440\n\t\tfor A in results:\n\t\t\tB=0\n\t\t\tif E.algorithm==Algorithm.LINE_TRACKING:B=abs(A.x_tail+(A.x_tail-A.x_head)//2-160)+abs(A.y_tail+(A.y_tail-A.y_head)//2-120)\n\t\t\telse:B=abs(A.x-160)+abs(A.y-120)\n\t\t\tif B<D:C,D=A,B\n\t\treturn C",
|
|
3
|
+
"mbbitbot": "from microbit import*\nfrom neopixel import*\nfrom utime import ticks_us,sleep_us\n_g1=200\n_g2=12\n_g3=NeoPixel(pin13,_g2)\n_g4=0\n_g5=0\ndef w(leftforward,leftbackward,rightforward,rightbackward):\n\tif leftforward>0 or rightforward>0:pin16.write_analog(leftforward+_g4);pin8.write_analog(leftbackward);pin14.write_analog(rightforward-_g4);pin12.write_analog(rightbackward)\n\telif leftbackward>0 or rightbackward>0:pin16.write_analog(leftforward);pin8.write_analog(leftbackward+_g4);pin14.write_analog(rightforward);pin12.write_analog(rightbackward-_g4)\n\telif leftforward==0 and rightforward==0 and leftbackward==0 and rightbackward==0:pin16.write_analog(0);pin8.write_analog(0);pin14.write_analog(0);pin12.write_analog(0)\ndef forward():w(_g1,0,_g1,0)\ndef backward():w(0,_g1,0,_g1)\ndef stop():w(0,0,0,0)\ndef right():w(0,_g1,_g1,0)\ndef left():w(_g1,0,0,_g1)\ndef set_led(pos,red,green,blue):_g3[pos]=red,green,blue;_g3.show()\ndef fill(red,green,blue):\n\tfor i in range(_g2):_g3[i]=red,green,blue\n\t_g3.show()\ndef getDistance():\n\tpin15.write_digital(1);sleep_us(10);pin15.write_digital(0);pin15.set_pull(pin15.NO_PULL)\n\twhile pin15.read_digital()==0:0\n\tstart=ticks_us()\n\twhile pin15.read_digital()==1:0\n\tend=ticks_us();echo=end-start;distance=int(.01715*echo);return distance\ndef calibrate(offset,differential=0):global _g4;global _g5;global _g8;_g5=max(min(int(offset),50),-50);_g4=max(min(int(differential),50),-50);_g8=max(min(arcScaling,50),-50);setSpeed(_g1/1023*100)\ndef setSpeed(percent):global _g1;speed=percent/100*1023;speed+=_g5/100*1023;speed=min(max(speed,0),1023);_g1=speed\ndef getLine(bit):\n\tmask=1<<bit;value=0\n\ttry:value=i2c.read(28,1)[0]\n\texcept OSError:pass\n\tif value&mask>0:return 1\n\telse:return 0\ndef getLight(index):\n\tif index==0:return pin1.read_analog()\n\telif index==1:return pin2.read_analog()\ndef leftArc(radius):speed=_g1;inner_wheel_speed=speed*(radius/(radius+1));w(inner_wheel_speed,0,speed,0)\ndef rightArc(radius):speed=_g1;inner_wheel_speed=speed*(radius/(radius+1));w(speed,0,inner_wheel_speed,0)",
|
|
4
|
+
"mbwait": "from microbit import button_a,button_b,pin0,pin1,pin2,pin_logo,sleep\nPOLLING_DELAY=100\ndef wait_for_press(button='any'):\n\tA=button;button_a.was_pressed();button_b.was_pressed()\n\tif A=='a'or A=='A':\n\t\twhile not button_a.was_pressed():sleep(POLLING_DELAY)\n\telif A=='b'or A=='B':\n\t\twhile not button_b.was_pressed():sleep(POLLING_DELAY)\n\telif A=='any'or A=='ANY':\n\t\twhile not button_a.was_pressed()and not button_b.was_pressed():sleep(POLLING_DELAY)\n\telif A=='both'or A=='ab'or A=='AB':\n\t\twhile not(button_a.is_pressed()and button_b.is_pressed()):sleep(POLLING_DELAY)\n\t\twhile button_a.is_pressed()or button_b.is_pressed():sleep(POLLING_DELAY)\n\telse:raise RuntimeError(\"Button to wait for must be either: 'a', 'b', 'any' or 'both'.\")\ndef wait_for_touch(pin='logo'):\n\tB=pin;A=pin_logo\n\tif B=='pin0':A=pin0\n\telif B=='pin1':A=pin1\n\telif B=='pin2':A=pin2\n\telif B=='logo'or B=='pin_logo'or B=='pinLogo':A=pin_logo\n\telse:raise RuntimeError(\"Argument 'pin' must be one of: 'pin_logo', 'pin0', 'pin1' or 'pin2'.\")\n\tA.set_touch_mode(A.CAPACITIVE)\n\twhile not A.is_touched():sleep(POLLING_DELAY)",
|
|
5
|
+
"mbled": "from neopixel import*\nimport gc\nfrom microbit import pin2\n_g1=24\n_g2=NeoPixel(pin2,_g1)\ndef fill(red,green,blue):\n\tfor i in range(_g1):_g2[i]=red,green,blue\n\t_g2.show()\ndef set_led(pos,red,green,blue):_g2[pos]=red,green,blue;_g2.show()\ndef clear():_g2.clear()\ndef shift_by(amount):\n\tshifted_copy=[None]*_g1\n\tfor n in range(0,_g1):next_i=(n+amount)%_g1;shifted_copy[n]=_g2[next_i]\n\tfor n in range(0,_g1):_g2[n]=shifted_copy[n]\n\t_g2.show()\ndef lerp_RGB(r1,g1,b1,r2,g2,b2,percent):\n\tif percent<.0 or percent>1e2:raise RuntimeError(\"Argument 'percent' must be between 0 and 100.\")\n\tred=max(0,min(255,round(r1+(r2-r1)*(percent/1e2))));green=max(0,min(255,round(g1+(g2-g1)*(percent/1e2))));blue=max(0,min(255,round(b1+(b2-b1)*(percent/1e2))));return red,green,blue",
|
|
6
|
+
"mbrobot_plus": "_A='Please switch on mbRobot!'\nfrom microbit import i2c,pin0,pin1,pin2,sleep\nimport machine,gc,music\n_g1=50\n_g2=.082\ndef w(d1,d2,s1,s2):\n\ttry:i2c.write(16,bytearray([0,d1,d2,s1,s2]))\n\texcept:print(_A)\ndef setSpeed(speed):\n\tA=speed;global _g1\n\tif A<30 and A!=0:setPID(1);_g1=A+30\n\telif A>=30 and A<32:setPID(0);_g1=A+2\n\telse:setPID(0);_g1=A\ndef setPID(pd):i2c.write(16,bytearray([10,pd]))\ndef stop():setPID(0);w(0,0,0,0)\ndef resetSpeed():setPID(0);A=50\ndef forward():w(1,_g1,1,_g1)\ndef backward():w(2,_g1,2,_g1)\ndef left():A=1.825-.0175*_g1;w(2,int(_g1*A),1,int(_g1*A))\ndef right():A=1.825-.0175*_g1;w(1,int(_g1*A),2,int(_g1*A))\ndef rightArc(r):\n\tA=abs(_g1)\n\tif r<_g2:B=0\n\telse:C=(r-_g2)/(r+_g2)*(1-A*A/200000);B=int(C*A)\n\tif _g1>0:w(1,A,1,B)\n\telse:w(2,B,2,A)\ndef leftArc(r):\n\tA=abs(_g1)\n\tif r<_g2:B=0\n\telse:C=(r-_g2)/(r+_g2)*(1-A*A/200000);B=int(C*A)\n\tif _g1>0:w(1,B,1,A)\n\telse:w(2,A,2,B)\ndef getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2-.5);return A if A>0 else 255\nclass Motor:\n\tdef __init__(A,id):A._id=2*id\n\tdef _f2(A,d,s):\n\t\ttry:i2c.write(16,bytearray([A._id,d,s]))\n\t\texcept:\n\t\t\tprint(_A)\n\t\t\twhile True:0\n\tdef rotate(A,s):\n\t\tB=abs(s)\n\t\tif s>0:A._f2(1,B)\n\t\telif s<0:A._f2(2,B)\n\t\telse:A._f2(0,0)\nclass LEDState:OFF=0;RED=1;GREEN=2;YELLOW=3;BLUE=4;PINK=5;CYAN=6;WHITE=7\ndef setLED(state,stateR=None):B=state;A=stateR;A=A or B;i2c.write(16,bytearray([11,B,A]))\ndef setLEDLeft(state):i2c.write(16,bytearray([11,state]))\ndef setLEDRight(state):i2c.write(16,bytearray([12,state]))\ndef setAlarm(on):\n\tif on:music.play(_g3,wait=False,loop=True)\n\telse:music.stop()\ndef beep():music.pitch(2000,200,wait=False)\ndef ir_read_values_as_byte():i2c.write(16,bytearray([29]));A=i2c.read(16,1);return~A[0]\ndef setServo(S,Angle):\n\tif S=='S1':A=20\n\tif S=='S2':A=21\n\tB=A,Angle;i2c.write(16,bytes(B))\nclass IR:L3=0;L2=1;L1=2;R1=3;R2=4;R3=5;masks=[1,2,4,8,16,32]\nclass IRSensor:\n\tdef __init__(A,index):A.index=index\n\tdef read_digital(A):B=ir_read_values_as_byte();return(B&IR.masks[A.index])>>A.index\nirLeft=IRSensor(IR.L1)\nirRight=IRSensor(IR.R1)\nirL1=IRSensor(IR.L1)\nirR1=IRSensor(IR.R1)\nirL2=IRSensor(IR.L2)\nirR2=IRSensor(IR.R2)\nirL3=IRSensor(IR.L3)\nirR3=IRSensor(IR.R3)\npin2.set_pull(pin2.NO_PULL)\nmotL=Motor(0)\nmotR=Motor(1)\ndelay=sleep\n_g3=['c6:1','r','c6,1','r','r','r']",
|
|
7
|
+
"mbrobot": "from microbit import i2c,pin1,pin2,pin8,pin12,pin13,pin14,pin15,sleep\nimport gc,machine,music,neopixel\n_g1=50\n_g2=40\n_g3=40\n_g4=bytearray(5)\n_g5=bytearray(2)\n_g6=bytes(b'\\x00\\x0b\\x0b\\x0c\\x0c\\r\\r\\r\\x0e\\x0e\\x0f\\x0f\\x0f\\x10\\x10\\x11\\x11\\x11\\x12\\x12\\x13\\x13\\x13\\x14\\x14\\x15\\x15\\x15\\x16\\x16\\x17\\x17\\x17\\x18\\x19\\x1a\\x1b\\x1b\\x1c\\x1d\\x1e\\x1f !\"##$%&\\'()*++,-./0123468:<?ADFILOSVZ^bgkpu{\\x81\\x87\\x8d\\x94\\x9b\\xa3\\xab\\xb4\\xbd\\xc6\\xd0\\xdb\\xe6\\xf2\\xff')\n_g7=0\n_g8=0\n_g9=0\n_g10=neopixel.NeoPixel(pin15,4)\nnp_rgb_pixels=_g10\n_g11=['c5:1','r','c5:1','r:3']\n_g12='Please connect to Maqueen robot and switch it on.'\ndef _f1(dirL,powerL,dirR,powerR):\n\tglobal _g4;_g4[1]=dirL;_g4[2]=powerL;_g4[3]=dirR;_g4[4]=powerR\n\ttry:i2c.write(16,_g4)\n\texcept:raise RuntimeError(_g12)\ndef _f2(side,dir,power):\n\tglobal _g4;_g4[1+side]=dir;_g4[2+side]=power\n\ttry:i2c.write(16,_g4)\n\texcept:raise RuntimeError(_g12)\ndef _f3(speed,offset):return min(_g6[speed]+offset,255)\ndef _f4(r):\n\tA=_g1;B=int(r*100);D=A-max(B+20,40)\n\tif D<=0:A=min(max(B+40,40),100)\n\tC=0\n\tif B>=4:E=(100-A)//2;C=(B*10-35)/(B*(11+(_g9-4)/10)+90+E);C=C*A\n\tF=_f3(int(C),0);G=_f3(int(A),0);return F,G\ndef calibrate(offset,differential=0,arcScaling=0):global _g8;global _g7;global _g9;_g7=max(min(int(offset),50),-10);_g8=max(min(int(differential),150),-150);_g9=max(min(arcScaling,50),-15);setSpeed(_g1)\ndef setSpeed(speed):\n\tglobal _g1;global _g2;global _g3;_g1=int(min(max(speed,0),100));A=_f3(_g1,_g7);B=round((1-_g1/100)*abs(_g8))if _g1>0 else 0;C=round(_g1/100*abs(_g8))\n\tif _g8>0:_g2=A-C;_g3=A+B\n\telse:_g2=A+B;_g3=A-C\ndef resetSpeed():setSpeed(50)\ndef stop():_f1(0,0,0,0)\ndef forward():_f1(0,_g2,0,_g3)\ndef backward():_f1(1,_g2,1,_g3)\ndef left():_f1(1,_g2,0,_g3)\ndef right():_f1(0,_g2,1,_g3)\ndef rightArc(radius):A,B=_f4(radius);_f1(0,B,0,A)\ndef leftArc(radius):A,B=_f4(radius);_f1(0,A,0,B)\nclass Motor:\n\tdef __init__(A,side):A._side=side\n\tdef rotate(B,speed):A=speed;C=int(min(max(abs(A),0),100));D=_f3(C,_g7);E=0 if A>0 else 1;_f2(B._side,E,D)\ndef setServo(servo,angle):\n\tB=angle;A=servo;global _g5\n\tif A=='S1'or A=='P0':_g5[0]=20\n\telif A=='S2'or A=='P1':_g5[0]=21\n\telse:raise ValueError(\"Unknown Servo. Please use 'S1' or 'S2'.\")\n\tif B<0 or B>180:raise ValueError('Invalid angle. Must be between 0 and 180')\n\t_g5[1]=B\n\ttry:i2c.write(16,_g5)\n\texcept:raise RuntimeError(_g12)\nclass IRSensor:\n\tdef __init__(A,pin):A._pin=pin\n\tdef read_digital(A):return A._pin.read_digital()\n\tdef read_analog(A):raise NameError('Maqueen Lite does not support reading analog sensor values.')\ndef getDistance():pin1.write_digital(1);pin1.write_digital(0);A=machine.time_pulse_us(pin2,1,50000);B=(A>>6)+(A>>10)+(A>>11)+(A>>12)+1;return max(min(B,500),0)if B>0 else 255\ndef setLED(state,stateR=None):B=state;A=stateR;A=A if A!=None else B;pin8.write_digital(B);pin12.write_digital(A)\ndef setLEDLeft(state):pin8.write_digital(state)\ndef setLEDRight(state):pin12.write_digital(state)\ndef fillRGB(red,green,blue):\n\tfor A in range(4):_g10[A]=red,green,blue\n\t_g10.show()\nsetRGB=fillRGB\ndef clearRGB():_g10.clear()\ndef posRGB(position,red,green,blue):\n\tA=position\n\tif A<0 or A>3:raise ValueError('invalid RGB-LED position. Must be 0,1,2 or 3.')\n\t_g10[A]=red,green,blue;_g10.show()\ndef setAlarm(state):\n\tif state:music.play(_g11,wait=False,loop=True)\n\telse:music.stop()\ndef beep():music.pitch(440,200,wait=False)\npin2.set_pull(pin2.NO_PULL)\ndelay=sleep\nirLeft=IRSensor(pin13)\nirRight=IRSensor(pin14)\nmotL=Motor(0)\nmotR=Motor(2)",
|
|
8
|
+
"mbrobot_plusV3": "_B=True\n_A=False\nfrom microbit import i2c,sleep,running_time,pin0,pin1,pin2\nimport neopixel,music\n_g1=bytearray(5)\n_g2=50\n_g3=50\n_g4=50\n_g5=bytes(b'\\x00\\x0f\\x10\\x10\\x11\\x12\\x12\\x13\\x13\\x14\\x15\\x15\\x16\\x16\\x17\\x18\\x18\\x19\\x19\\x1a\\x1b\\x1b\\x1c\\x1c\\x1d\\x1e\\x1e\\x1f\\x1f !!\"\"#$$%%&\\')*+,-./0123456789:;;<>?ACEGIKMPRUX[^aeimquz\\x7f\\x84\\x89\\x8f\\x95\\x9b\\xa2\\xa9\\xb1\\xb9\\xc1\\xca\\xd3\\xdd\\xe8\\xf3\\xff')\n_g6=0\n_g7='Please connect to Maqueen robot and switch it on.'\n_g8=neopixel.NeoPixel(pin1,4)\n_g9=['c5:1','r','c5,1','r:3']\n_g10=bytearray(1)\n_g11=bytearray(2)\n_g12=16\n_g13=25\n_g14=131\n_g15=8\ndef _f1(reg):_g10[0]=reg;i2c.write(_g12,_g10)\ndef _f2(reg,val):_g11[0]=reg;_g11[1]=val;i2c.write(_g12,_g11)\ndef _f3(dirL,powerL,dirR,powerR):\n\tglobal _g1;_g1[1]=dirL;_g1[2]=powerL;_g1[3]=dirR;_g1[4]=powerR\n\ttry:i2c.write(16,_g1)\n\texcept:raise RuntimeError(_g7)\ndef _f4(side,dir,power):\n\tglobal _g1;_g1[1+side]=dir;_g1[2+side]=power\n\ttry:i2c.write(16,_g1)\n\texcept:raise RuntimeError(_g7)\ndef setSpeed(speed):A=speed;global _g2;global _g3;global _g4;_g2=int(min(max(A,0),100));_g3=int(round(2.4*A+14));_g4=int(round(2.4*A+14))\ndef resetSpeed():setSpeed(50)\ndef stop():_f3(0,0,0,0)\ndef forward():_f3(0,_g3,0,_g4)\ndef backward():_f3(1,_g3,1,_g4)\ndef left():_f3(1,_g3,0,_g4)\ndef right():_f3(0,_g3,1,_g4)\ndef _f5(speed,offset):return min(_g5[speed]+offset,255)\ndef _f6(r):\n\tB=int(r*100);A=_g2\n\tif A<25:A=25\n\tC=0\n\tif B>5:\n\t\tD=A*(3*_g6-A-9*B+220);E=-14*_g6+A-200+3*A-10*B-290;C=int(D/E)\n\t\tif C<2:C=2 if B>15 else 1\n\tF=_f5(int(C),0);G=_f5(int(A),0);return F,G\ndef rightArc(radius):A,B=_f6(radius);_f3(0,B,0,A)\ndef leftArc(radius):A,B=_f6(radius);_f3(0,A,0,B)\nclass Motor:\n\tdef __init__(A,side):A._side=side\n\tdef rotate(B,speed):A=speed;C=int(min(max(abs(A),0),100));D=C;E=0 if A>0 else 1;_f4(B._side,E,D)\ndef setServo(servo,angle):\n\tD=angle;C=servo\n\tif D<0 or D>180:raise ValueError('Invalid angle. Must be between 0 and 180')\n\tif C in['P0','S1']:A=pin0\n\telif C in['P1','S2']:A=pin1\n\telif C in['P2','S3']:A=pin2\n\telse:raise ValueError('Valid servo names: S1, S2, S3 or P0, P1, P2')\n\tB=(_g14-_g13)*int(D);E=(B>>8)+(B>>10)+(B>>11)+(B>>12);F=_g13+E;A.set_analog_period(20);A.write_analog(F)\nclass IRSensor:\n\t_g19=bytes(b'\\x1d')\n\tdef __init__(A,index):A.index=index\n\tdef read_digital(A):\n\t\ttry:i2c.write(16,IRSensor._g19)\n\t\texcept:raise RuntimeError(_g7)\n\t\tB=~i2c.read(16,1)[0];return(B&2**A.index)>>A.index\n\tdef read_analog(A):\n\t\ttry:_f1(29)\n\t\texcept:raise RuntimeError(_g7)\n\t\tB=i2c.read(16,11);return B[2+2*A.index]<<8|B[1+2*A.index]\ndef setLEDs(rgbl,rgbr):_f2(11,rgbl);_f2(12,rgbr)\ndef setLED(state,stateR=None):B=state;A=stateR;A=A if A!=None else B;setLEDs(B,A)\ndef setLEDLeft(rgbl):_f2(11,rgbl)\ndef setLEDRight(rgbr):_f2(12,rgbr)\ndef fillRGB(red,green,blue):_g8.clear();_g8.fill((red,green,blue));_g8.show()\ndef setRGB(r,g,b):fillRGB(r,g,b)\ndef clearRGB():_g8.clear()\ndef posRGB(position,red,green,blue):\n\tA=position\n\tif A<0 or A>3:raise ValueError('invalid RGB-LED position. Must be 0,1,2 or 3.')\n\t_g8[A]=red,green,blue;_g8.show()\ndef setAlarm(state):\n\tif state:music.play(_g9,wait=_A,loop=_B)\n\telse:music.stop()\ndef beep():music.pitch(440,200,wait=_A)\ndef readLightIntensity(side):\n\t_f1(78);A=i2c.read(16,4,repeat=_A)\n\tif side==1:return A[0]<<8|A[1]\n\telse:return A[2]<<8|A[3]\ndef setPatrolSpeed(speed):_f2(63,speed)\ndef setIntersectionRunMode(mode):_f2(69,mode)\ndef setTRordRunMode(mode):_f2(70,mode)\ndef setLeftOrStraightRunMode(mode):_f2(71,mode)\ndef setRightOrStraightRunMode(mode):_f2(72,mode)\ndef patrolling(patrol):\n\tif patrol==1:A=5\n\telse:A=8\n\t_f2(60,A)\ndef intersectionDetecting():_f1(61);A=i2c.read(16,1)[0];return A\ndef pidControlDistance(dir,distance,interruption):\n\tA=distance;C=2\n\tif A>=6000:A=60000\n\t_f2(64,dir);_f2(85,C);_f2(65,A>>8);_f2(66,A);_f2(60,6)\n\tif interruption==1:\n\t\t_f1(87);B=i2c.read(16,1)\n\t\twhile B[0]==1:sleep(10);B=i2c.read(16,1)\ndef pidControlAngle(angle,interruption):\n\tA=angle;D=2\n\tif A>=0:B=1\n\telse:B=2;A=-A\n\t_f2(67,B);_f2(86,D);_f2(68,A);_f2(60,6)\n\tif interruption==1:\n\t\t_f1(87);C=i2c.read(16,1)\n\t\twhile C[0]==1:sleep(10);C=i2c.read(16,1)\ndef pidControlStop():_f2(60,16)\ndef readRealTimeSpeed(type):\n\t_f2(76,1);A=i2c.read(16,2)\n\tif type==1:return A[0]/5\n\telse:return A[1]/5\ndef _f7(cmd,args=[]):\n\tB=len(args);C=B+1;A=bytearray(4+B);A[0]=85;A[1]=C>>8&255;A[2]=C&255;A[3]=cmd\n\tfor(D,E)in enumerate(args):A[4+D]=E\n\ti2c.write(51,A)\ndef _f8(expectedCommand):\n\tF=1000;J=32;G=running_time();B=_A;A=None;C=_A\n\twhile running_time()-G<F and C==_A:\n\t\tH=i2c.read(51,1)[0]\n\t\tif H==83:C=_B\n\t\telif H==99:return B,A\n\t\tsleep(16)\n\tif C==_B:\n\t\tD=i2c.read(51,3);K=D[0];L=D[1]|D[2]<<8\n\t\tif K==expectedCommand:\n\t\t\tB=_B;A=bytearray();E=L;M=min(E,J)\n\t\t\twhile running_time()-G<F and E>0:\n\t\t\t\ttry:I=i2c.read(51,M);A.extend(I);E-=len(I)\n\t\t\t\texcept:sleep(1)\n\treturn B,A\ndef setLidarMode(mode=8):\n\tA=mode;global _g15\n\tif A not in[4,8]:raise ValueError('Lidar mode must be 4 or 8')\n\tC='4x4'if A==4 else'8x8';print('Switching Lidar Mode to '+C+'.\\nPlease wait up to 10 seconds.');B=_A\n\tfor D in range(10):\n\t\t_f7(1,[0,0,0,A]);B,E=_f8(1)\n\t\tif B==_B:break\n\t\tsleep(17)\n\tif B:_g15=A;sleep(5000)\n\telse:raise RuntimeError('Failed to switch Lidar Mode')\ndef getDistanceAt(x_pos,y_pos):\n\t_f7(3,[x_pos,y_pos]);B,A=_f8(3)\n\tif B and len(A)>=2:C=(A[0]|A[1]<<8)//10;return C\n\telse:return 1023\ndef getDistanceList():\n\t_f7(2);D,A=_f8(2)\n\tif D and len(A)>=32:\n\t\tB=[]\n\t\tfor C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)\n\t\treturn B\n\telse:return[]\ndef getDistance():global _g15;A=int(_g15/2);B=getDistanceAt(A-1,A-1);C=getDistanceAt(A,A-1);D=getDistanceAt(A-1,A);E=getDistanceAt(A,A);F=[B,C,D,E];return min(F)\ndef getDistanceGrid():\n\t_f7(2);G,A=_f8(2)\n\tif G and len(A)>=32:\n\t\tB=[];C=16 if len(A)==128 else 8\n\t\tfor D in range(0,len(A),C):\n\t\t\tE=[]\n\t\t\tfor F in range(0,C,2):H=A[D+F]|A[D+F+1]<<8;E.append(H//10)\n\t\t\tB.append(E)\n\t\treturn B\n\telse:return[]\ndef getDistanceColumn(index):\n\t_f7(5,[index]);D,A=_f8(5)\n\tif D and len(A)>=8:\n\t\tB=[]\n\t\tfor C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)\n\t\treturn B\n\treturn[]\ndef getDistanceRow(index):\n\t_f7(6,[index]);D,A=_f8(6)\n\tif D and len(A)>=8:\n\t\tB=[]\n\t\tfor C in range(0,len(A),2):E=A[C]|A[C+1]<<8;B.append(E//10)\n\t\treturn B\n\treturn[]\npin2.set_pull(pin2.NO_PULL)\ndelay=sleep\nirR2=IRSensor(0)\nirR1=IRSensor(1)\nirRight=irR1\nirM=IRSensor(2)\nirL1=IRSensor(3)\nirLeft=irL1\nirL2=IRSensor(4)\nmotL=Motor(0)\nmotR=Motor(2)",
|
|
9
|
+
"mbmarsrover": "from microbit import*\nfrom neopixel import*\nimport utime\n_g1=[0,9,11,13,15]\n_g2=[0,0,0,0,0]\n_g3=False\n_g4=4\n_g5=NeoPixel(pin2,_g4)\n_g6=50\n_g7=40\n_g8=40\n_g9=0\n_g10=0\n_g11=0\n_g12=500\n_g13=29.1\ndef _f1(dirL,powerL,dirR,powerR):pinsL=pin1,pin12;pinsR=pin8,pin0;pinsL[dirL].write_analog(powerL);pinsL[1-dirL].write_analog(0);pinsR[dirR].write_analog(powerR);pinsR[1-dirR].write_analog(0)\ndef _f2(side,direction,power):\n\tif side==0:pins=pin1,pin12\n\telif side==1:pins=pin8,pin0\n\tpins[direction].write_analog(power);pins[1-direction].write_analog(0)\ndef _f3(r):\n\touterSpeed=_g6;rCm=int(r*100);threshold=outerSpeed-max(rCm+20,40)\n\tif threshold<=0:outerSpeed=min(max(rCm+40,40),100)\n\treducedSpeed=0\n\tif rCm>=4:flattening=(100-outerSpeed)//2;reducedSpeed=(rCm*10-35)/(rCm*(11+(_g11-4)/10)+90+flattening);reducedSpeed=reducedSpeed*outerSpeed\n\tinnerByte=_f6(int(reducedSpeed),0);outerByte=_f6(int(outerSpeed),0);return innerByte,outerByte\ndef _f4():global _g3;_g3=True;i2cData=bytearray(2);i2cData[0]=0;i2cData[1]=16;i2c.write(64,i2cData);i2cData[0]=254;i2cData[1]=101;i2c.write(64,i2cData);i2cData[0]=0;i2cData[1]=129;i2c.write(64,i2cData)\ndef _f5(pin,value,timeout):\n\tstart_time=utime.ticks_us()\n\twhile pin.read_digital()!=value:\n\t\tif utime.ticks_diff(utime.ticks_us(),start_time)>timeout:return 0\n\tstart_time=utime.ticks_us()\n\twhile pin.read_digital()==value:\n\t\tif utime.ticks_diff(utime.ticks_us(),start_time)>timeout:return 0\n\treturn utime.ticks_diff(utime.ticks_us(),start_time)\ndef calibrate(offset,differential=0,arcScaling=0):global _g10;global _g9;global _g11;_g9=max(min(int(offset),500),-50);_g10=max(min(int(differential),150),-150);_g11=max(min(arcScaling,50),-15);setSpeed(_g6)\ndef setSpeed(speed):\n\tglobal _g6;global _g7;global _g8;_g6=int(min(max(speed,0),100));powerValue=_f6(_g6,_g9);boost=round((1-_g6/100)*abs(_g10))if _g6>0 else 0;reduction=round(_g6/100*abs(_g10))\n\tif _g10>0:_g7=powerValue-reduction;_g8=powerValue+boost\n\telse:_g7=powerValue+boost;_g8=powerValue-reduction\ndef _f6(speed,offset):analogValue=int(speed*1023/100)+offset;return min(max(analogValue,0),1023)\ndef stop():_f1(0,0,0,0)\ndef forward():_f1(0,_g7,0,_g8)\ndef backward():_f1(1,_g7,1,_g8)\ndef setServo(servoNum,angle):\n\tglobal _g1,_g3\n\tif _g3==False:_f4()\n\toffsetNum=servoNum;servoNum=_g1[servoNum];i2cData=bytearray(2);start=0;angle=max(min(angle,90),-90);stop=396+(angle+_g2[offsetNum])*223/90;i2cData[0]=6+servoNum*4+2;i2cData[1]=int(stop)+255;i2c.write(64,i2cData);i2cData[0]=6+servoNum*4+3;i2cData[1]=int(stop)>>8;i2c.write(64,i2cData)\ndef clearServos():setServo(0,0);setServo(1,0);setServo(2,0);setServo(3,0);setServo(4,0);sleep(500)\ndef steer(angle):angle=max(min(angle,45),-45);setServo(1,angle);setServo(2,-angle);setServo(3,-angle);setServo(4,angle);sleep(500)\ndef setLED(pos,red,green,blue):_g5[pos]=red,green,blue;_g5.show()\ndef fill(red,green,blue):\n\tfor i in range(_g4):_g5[i]=red,green,blue\n\t_g5.show()\ndef getDistance():\n\ttrig=pin13;echo=pin13;d=10;trig.set_pull(trig.NO_PULL)\n\tfor _ in range(10):\n\t\ttrig.write_digital(0);utime.sleep_us(2);trig.write_digital(1);utime.sleep_us(10);trig.write_digital(0);duration=_f5(echo,1,_g12*_g13)\n\t\tif duration>0:d=duration;break\n\treturn round(d/_g13)\ndef calibrateServo(pos,angleDifferential):global _g2;angleDifferential=max(min(angleDifferential,90),-90);_g2[pos]=angleDifferential;clearServos()",
|
|
10
|
+
"mbrobotmot": "import gc\nfrom microbit import i2c,pin1,pin2,pin8,pin12,pin13,pin14,sleep\nimport machine\nclass Motor:\n\tdef __init__(A,id):A._id=2*id\n\tdef rotate(A,s):\n\t\tB=abs(s)\n\t\tif s>0:A._f2(0,B)\n\t\telif s<0:A._f2(1,B)\n\t\telse:A._f2(0,0)\n\tdef _f2(A,d,s):\n\t\ttry:i2c.write(16,bytearray([A._id,d,s]))\n\t\texcept:\n\t\t\tprint('Please switch on mbRobot!')\n\t\t\twhile True:0\ndelay=sleep\ndef getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2+.5);return A if A>0 else 255\ndef setLED(on):pin8.write_digital(on);pin12.write_digital(on)\npin2.set_pull(pin2.NO_PULL)\nirLeft=pin13\nirRight=pin14\nledLeft=pin8\nledRight=pin12\nmotL=Motor(0)\nmotR=Motor(1)",
|
|
11
|
+
"controller": "_B=False\n_A=1.\nfrom microbit import run_every,pin13,pin14,pin15,pin16,pin8,pin1,pin2,pin12,button_a,button_b,sleep\nclass _Controller_Button:\n\tdef __init__(A,pin):B=pin;A._pin=B;A.previous_state=0;A._press_count=0;A._pressed_before=_B;B.set_pull(B.PULL_UP)\n\tdef _f3(A):\n\t\tB=1-A._pin.read_digital()\n\t\tif B==1 and A.previous_state==0:A._press_count+=1;A._pressed_before=True\n\t\tA.previous_state=B\n\tdef is_pressed(A):return _B if A._pin.read_digital()else True\n\tdef was_pressed(A):B=A._pressed_before;A._pressed_before=_B;return B\n\tdef get_presses(A):B=A._press_count;A._press_count=0;return B\nclass _Controller_Analog_Stick:\n\tdef __init__(A,pinX,pinY,pinZ):A.pin_x=pinX;A.pin_y=pinY;A.button_z=_Controller_Button(pinZ);A.dead_zone=.01;A.center_x=0;A.center_y=0;A.min_x=-1;A.max_x=1;A.min_y=-1;A.max_y=1\n\tdef calibrate(A,dead_zone,center_x=.0,center_y=.0,x_min=-_A,x_max=_A,y_min=-_A,y_max=_A):A.dead_zone=min(.2,max(.01,dead_zone));A.center_x=min(.4,max(-.4,center_x));A.center_y=min(.5,max(-.5,center_y));A.min_x=min(-.5,max(-_A,x_min));A.max_x=min(_A,max(.5,x_max));A.min_y=min(-.5,max(-_A,y_min));A.max_y=min(_A,max(.5,y_max))\n\tdef _f5(C,value,center,v_min,v_max):\n\t\tB=center;A=value-_A-B\n\t\tif abs(A)-C.dead_zone/2.>.0:\n\t\t\tif A<.0:A=A/abs(v_min-B)\n\t\t\telse:A=A/abs(v_max-B)\n\t\tA=min(_A,max(-_A,A));A=.0 if abs(A)<=C.dead_zone else A;return A\n\tdef get_x(A):B=A.pin_x.read_analog()/512.;C=A._f5(B,A.center_x,A.min_x,A.max_x);return C\n\tdef get_y(A):B=A.pin_y.read_analog()/512.;C=A._f5(B,A.center_y,A.min_y,A.max_y);return C\n\tdef get_z(A):return 1 if A.button_z.is_pressed()else 0\n\tdef is_pressed(A):return A.button_z.is_pressed()\n\tdef was_pressed(A):return A.button_z.was_pressed()\n\tdef get_presses(A):return A.button_z.get_presses()\ndef vibrate(state):pin12.write_digital(state)\njoystick=_Controller_Analog_Stick(pin1,pin2,pin8)\nbutton_z=joystick.button_z\nbutton_c=_Controller_Button(pin13)\nbutton_green=button_c\nbutton_d=_Controller_Button(pin14)\nbutton_yellow=button_d\nbutton_e=_Controller_Button(pin15)\nbutton_red=button_e\nbutton_f=_Controller_Button(pin16)\nbutton_blue=button_f\ntrigger_left=button_a\ntrigger_right=button_b\ndef _f1():global button_c;global button_d;global button_e;global button_f;global joystick;button_c._f3();button_d._f3();button_e._f3();button_f._f3();joystick.button_z._f3()\nrun_every(_f1,days=0,h=0,min=0,s=0,ms=33)",
|
|
12
|
+
"mbxgo": "from microbit import*\n_g1=50\n_g2=False\n_g3=pin14\n_g4=pin13\ndef checkInit(func):\n\tdef wrapper(*args,**kwargs):\n\t\tglobal _g2\n\t\tif not _g2:init_xgo_serial(_g3,_g4)\n\t\treturn func(*args,**kwargs)\n\treturn wrapper\ndef _f1(speed,in_min,in_max,out_min,out_max):return(speed-in_min)*(out_max-out_min)//(in_max-in_min)+out_min\n@checkInit\ndef _f2(direction,speed):\n\tmove_buffer=bytearray(9);move_buffer[0]=85;move_buffer[1]=0;move_buffer[2]=9;move_buffer[3]=0;move_buffer[7]=0;move_buffer[8]=170;speed=max(0,min(100,speed))\n\tif direction==0:move_buffer[4]=48;move_buffer[5]=_f1(speed,0,100,128,255)\n\telif direction==1:move_buffer[4]=48;move_buffer[5]=_f1(speed,0,100,128,0)\n\telif direction==2:move_buffer[4]=49;move_buffer[5]=_f1(speed,0,100,128,0)\n\telif direction==3:move_buffer[4]=49;move_buffer[5]=_f1(speed,0,100,128,255)\n\tmove_buffer[6]=~(9+move_buffer[4]+move_buffer[5])&255;uart.write(move_buffer)\n@checkInit\ndef clampX(milimeters=50):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=115;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=milimeters;clampBuffer[6]=~(124+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)\n@checkInit\ndef clampZ(milimeters=50):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=116;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=milimeters;clampBuffer[6]=~(125+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)\n@checkInit\ndef clamp(force):clampBuffer=bytearray(9);clampBuffer[0]=85;clampBuffer[1]=0;clampBuffer[2]=9;clampBuffer[3]=0;clampBuffer[4]=113;clampBuffer[7]=0;clampBuffer[8]=170;clampBuffer[5]=force;clampBuffer[6]=~(122+clampBuffer[5])&255;uart.write(clampBuffer);sleep(1000)\ndef init_xgo_serial(tx_pin,rx_pin,baudrate=115200):global _g2;uart.init(baudrate=baudrate,tx=tx_pin,rx=rx_pin);init_action();_g2=True\ndef init_action():commands_buffer=bytearray(9);commands_buffer[0]=85;commands_buffer[1]=0;commands_buffer[2]=9;commands_buffer[3]=0;commands_buffer[4]=62;commands_buffer[5]=255;commands_buffer[6]=185;commands_buffer[7]=0;commands_buffer[8]=170;uart.write(commands_buffer);sleep(2000)\n@checkInit\ndef action(id):commands_buffer=bytearray(9);commands_buffer[0]=85;commands_buffer[1]=0;commands_buffer[2]=9;commands_buffer[3]=0;commands_buffer[4]=62;commands_buffer[5]=id;commands_buffer[6]=~(71+id)&255;commands_buffer[7]=0;commands_buffer[8]=170;uart.write(commands_buffer);sleep(2000)\ndef changeInit(tx,rx):global _g3;global _g4;_g3=tx;_g4=rx;init_xgo_serial(_g3,_g4)\n@checkInit\ndef setSpeed(speed):global _g1;_g1=speed\ndef forward():_f2(0,_g1)\ndef backward():_f2(1,_g1)\ndef left():_f2(2,_g1)\ndef right():_f2(3,_g1)",
|
|
13
|
+
"mbglow": "from microbit import*\n_g1=0\n_g2=0\n_g3=0\n_g4=50\n_g5=True\n_g6=False\ndef makeGlow():global _g6;display.set_pixel(2,2,9);_g6=True\ndef clear():display.clear()\ndef forward():_f1(1)\ndef back():_f1(-1)\ndef right(angle):global _g3;_g3=(_g3+angle)%360\ndef left(angle):right(-angle)\ndef setPos(x,y):global _g1,_g2;_g1=x;_g2=y;_f2()\ndef getPos():return _g1,_g2\ndef setSpeed(speed):global _g4;_g4=speed\ndef showTrace(enable):global _g5;_g5=enable\ndef isLit():return display.get_pixel(_g1+2,4-(_g2+2))==9\ndef _f1(s):\n\tglobal _g1,_g2;sleep(2000-_g4*20);d=_g3//45\n\tif d in[1,2,3]:_g1+=s\n\tif d in[5,6,7]:_g1-=s\n\tif d in[0,1,7]:_g2+=s\n\tif d in[3,4,5]:_g2-=s\n\t_f2()\ndef _f2():\n\tif not _g6:print('Use \"makeGlow()\" to create a Glow.');raise Exception('Glow not initialized.')\n\tif not _g5:display.clear()\n\tif-2<=_g1<=2 and-2<=_g2<=2:display.set_pixel(_g1+2,4-(_g2+2),9)",
|
|
14
|
+
"mbthetabot": "from microbit import*\nfrom utime import ticks_us,sleep_us\nfrom neopixel import*\n_g1=50\n_g2=40\n_g3=40\n_g4=bytes(b'\\x00\\x0b\\x0b\\x0c\\x0c\\r\\r\\r\\x0e\\x0e\\x0f\\x0f\\x0f\\x10\\x10\\x11\\x11\\x11\\x12\\x12\\x13\\x13\\x13\\x14\\x14\\x15\\x15\\x15\\x16\\x16\\x17\\x17\\x17\\x18\\x19\\x1a\\x1b\\x1b\\x1c\\x1d\\x1e\\x1f !\"##$%&\\'()*++,-./0123468:<?ADFILOSVZ^bgkpu{\\x81\\x87\\x8d\\x94\\x9b\\xa3\\xab\\xb4\\xbd\\xc6\\xd0\\xdb\\xe6\\xf2\\xff')\n_g5=0\n_g6=0\n_g7=0\n_g8=34\n_g9=14\ndef _f1(dirL,powerL,dirR,powerR):pinsL=pin14,pin13;pinsR=pin16,pin15;pinsL[dirL].write_analog(powerL);pinsL[1-dirL].write_analog(0);pinsR[dirR].write_analog(powerR);pinsR[1-dirR].write_analog(0)\ndef _f2(side,direction,power):\n\tif side==0:pins=pin14,pin13\n\telif side==2:pins=pin16,pin15\n\tpins[direction].write_analog(power);pins[1-direction].write_analog(0)\ndef _f3(r):\n\touterSpeed=_g1;rCm=int(r*100);threshold=outerSpeed-max(rCm+20,40)\n\tif threshold<=0:outerSpeed=min(max(rCm+40,40),100)\n\treducedSpeed=0\n\tif rCm>=4:flattening=(100-outerSpeed)//2;reducedSpeed=(rCm*10-35)/(rCm*(11+(_g7-4)/10)+90+flattening);reducedSpeed=reducedSpeed*outerSpeed\n\tinnerByte=_f4(int(reducedSpeed),0);outerByte=_f4(int(outerSpeed),0);return innerByte,outerByte\ndef calibrate(offset,differential=0,arcScaling=0):global _g6;global _g5;global _g7;_g5=max(min(int(offset),150),-10);_g6=max(min(int(differential),150),-150);_g7=max(min(arcScaling,50),-15);setSpeed(_g1)\ndef setSpeed(speed):\n\tglobal _g1;global _g2;global _g3;_g1=int(min(max(speed,0),100));powerByte=_f4(_g1,_g5);boost=round((1-_g1/100)*abs(_g6))if _g1>0 else 0;reduction=round(_g1/100*abs(_g6))\n\tif _g6>0:_g2=powerByte-reduction;_g3=powerByte+boost\n\telse:_g2=powerByte+boost;_g3=powerByte-reduction\ndef _f4(speed,offset):speedIndex=int(speed*(len(_g4)-1)/100);return min(_g4[speedIndex]+offset,1023)\ndef stop():_f1(0,0,0,0)\ndef forward():_f1(0,_g2,0,_g3)\ndef backward():_f1(1,_g2,1,_g3)\ndef left():_f1(1,_g2,0,_g3)\ndef right():_f1(0,_g2,1,_g3)\ndef rightArc(radius):inner,outer=_f3(radius);_f1(0,outer,0,inner)\ndef leftArc(radius):inner,outer=_f3(radius);_f1(0,inner,0,outer)\ndef getDistance():\n\tpin12.write_digital(1);sleep_us(10);pin12.write_digital(0);pin12.set_pull(pin15.NO_PULL)\n\twhile pin12.read_digital()==0:0\n\tstart=ticks_us()\n\twhile pin12.read_digital()==1:0\n\tend=ticks_us();echo=end-start;distance=int(.01715*echo);return distance\ndef setLED(position,red,green,blue):global _g8;i2c_data=bytearray(5);i2c_data[0]=1;i2c_data[1]=position;i2c_data[2]=red;i2c_data[3]=green;i2c_data[4]=blue;i2c.write(_g8,i2c_data)\ndef fill(red,green,blue):\n\tfor position in range(_g9):setLED(position,red,green,blue)\ndef readLine(side):i2c.write(_g8,bytearray([side+1]),False);result=i2c.read(_g8,2);result=result[0]+(result[1]<<8);return result\ndef readLight(side):i2c.write(_g8,bytearray([side+3]),False);result=i2c.read(_g8,2);result=result[0]+(result[1]<<8);return result",
|
|
15
|
+
"mbrobot_legacy": "import gc\nfrom microbit import i2c,pin1,pin2,pin8,pin12,pin13,pin14,sleep\nimport machine\n_g1=.097\ndef w(d1,d2,s1,s2):\n\ttry:i2c.write(16,bytearray([0,d1,s1]));i2c.write(16,bytearray([2,d2,s2]))\n\texcept:\n\t\tprint('Please switch on mbRobot!')\n\t\twhile True:0\ndef setSpeed(speed):\n\tA=speed;global _g2\n\tif A<20:_g2=A+5\n\telse:_g2=A\ndef forward():w(0,0,_g2,_g2)\ndef backward():w(1,1,_g2,_g2)\ndef stop():w(0,0,0,0)\ndef right():w(0 if _g2>0 else 1,1 if _g2>0 else 0,int(_g2*.9),int(_g2*.9))\ndef left():w(1 if _g2>0 else 0,0 if _g2>0 else 1,int(_g2*.9),int(_g2*.9))\ndef rightArc(r):\n\tA=abs(_g2)\n\tif r<_g1:B=0\n\telse:C=(r-_g1)/(r+_g1)*(1-A*A/200000);B=int(C*A)\n\tif _g2>0:w(0,0,A,B)\n\telse:w(1,1,B,A)\ndef leftArc(r):\n\tA=abs(_g2)\n\tif r<_g1:B=0\n\telse:C=(r-_g1)/(r+_g1)*(1-A*A/200000);B=int(C*A)\n\tif _g2>0:w(0,0,B,A)\n\telse:w(1,1,A,B)\nexit=stop\ndelay=sleep\ndef getDistance():pin1.write_digital(1);pin1.write_digital(0);B=machine.time_pulse_us(pin2,1,50000);A=int(B/58.2+.5);return A if A>0 else 255\ndef setLED(on):pin8.write_digital(on);pin12.write_digital(on)\ndef setServo(S,Angle):\n\tif S=='S1':A=20\n\tif S=='S2':A=21\n\tB=A,Angle;i2c.write(16,bytes(B))\npin2.set_pull(pin2.NO_PULL)\n_g2=50\nirLeft=pin13\nirRight=pin14\nledLeft=pin8\nledRight=pin12\nforward()",
|
|
16
|
+
"mbalarm": "import music\n_g1=['c6:1','r','c6,1','r','r','r']\ndef setAlarm(on):\n\tif on:music.play(_g1,wait=False,loop=True)\n\telse:music.stop()\ndef beep():music.pitch(2000,200,wait=False)",
|
|
17
|
+
"mbminibit": "from microbit import*\nfrom neopixel import*\nimport utime\n_g1=4\n_g2=NeoPixel(pin13,_g1)\n_g3=50\n_g4=90\n_g5=90\n_g6=0\n_g7=0\n_g8=0\n_g9=500\n_g10=29.1\ndef _f1(dirL,powerL,dirR,powerR):pin8.write_analog(powerL if dirL==1 else 0);pin12.write_analog(0 if dirL==1 else powerL);pin16.write_analog(0 if dirR==1 else powerR);pin14.write_analog(powerR if dirR==1 else 0)\ndef _f2(pin,value,timeout):\n\tstart_time=utime.ticks_us()\n\twhile pin.read_digital()!=value:\n\t\tif utime.ticks_diff(utime.ticks_us(),start_time)>timeout:return 0\n\tstart_time=utime.ticks_us()\n\twhile pin.read_digital()==value:\n\t\tif utime.ticks_diff(utime.ticks_us(),start_time)>timeout:return 0\n\treturn utime.ticks_diff(utime.ticks_us(),start_time)\ndef _f3(r):\n\touterSpeed=_g3\n\tif r>0:innerSpeed=outerSpeed*max(.2,min(1,1-r/100))\n\telse:innerSpeed=0\n\tinnerByte=_f4(int(innerSpeed),0);outerByte=_f4(int(outerSpeed),0);return innerByte,outerByte\ndef _f4(speed,offset):analogValue=int(speed*255/100)+offset;return min(max(analogValue,0),255)\ndef calibrate(offset,differential=0,arcScaling=0):global _g7;global _g6;global _g8;_g6=max(min(int(offset),100),-10);_g7=max(min(int(differential),150),-150);_g8=max(min(arcScaling,50),-15);setSpeed(_g3)\ndef setSpeed(speed):\n\tglobal _g3;global _g4;global _g5;_g3=int(min(max(speed,0),100));powerByte=_f4(_g3,_g6);boost=round((1-_g3/100)*abs(_g7))if _g3>0 else 0;reduction=round(_g3/100*abs(_g7))\n\tif _g7>0:_g4=powerByte-reduction;_g5=powerByte+boost\n\telse:_g4=powerByte+boost;_g5=powerByte-reduction\ndef stop():_f1(0,0,0,0)\ndef forward():_f1(0,_g4,0,_g5)\ndef backward():_f1(1,_g4,1,_g5)\ndef left():_f1(1,_g4,0,_g5)\ndef right():_f1(0,_g4,1,_g5)\ndef rightArc(radius):inner,outer=_f3(radius);_f1(0,outer,0,inner)\ndef leftArc(radius):inner,outer=_f3(radius);_f1(0,inner,0,outer)\ndef setLED(pos,red,green,blue):_g2[pos]=red,green,blue;_g2.show()\ndef fill(red,green,blue):\n\tfor i in range(_g1):_g2[i]=red,green,blue\n\t_g2.show()\ndef getDistance():\n\ttrig=pin15;echo=pin15;d=10;trig.set_pull(trig.NO_PULL)\n\tfor _ in range(10):\n\t\ttrig.write_digital(0);utime.sleep_us(2);trig.write_digital(1);utime.sleep_us(10);trig.write_digital(0);duration=_f2(echo,1,_g9*_g10)\n\t\tif duration>0:d=duration;break\n\treturn round(d/_g10)",
|
|
18
|
+
"mbrobot_plusV2": "from microbit import i2c,pin0,pin1,pin2,pin13,pin14,pin15,sleep\nimport gc,machine,music,neopixel\n_g1=50\n_g2=50\n_g3=50\n_g4=bytearray(5)\n_g5=bytes(b'\\x00\\x0f\\x10\\x10\\x11\\x12\\x12\\x13\\x13\\x14\\x15\\x15\\x16\\x16\\x17\\x18\\x18\\x19\\x19\\x1a\\x1b\\x1b\\x1c\\x1c\\x1d\\x1e\\x1e\\x1f\\x1f !!\"\"#$$%%&\\')*+,-./0123456789:;;<>?ACEGIKMPRUX[^aeimquz\\x7f\\x84\\x89\\x8f\\x95\\x9b\\xa2\\xa9\\xb1\\xb9\\xc1\\xca\\xd3\\xdd\\xe8\\xf3\\xff')\n_g6=0\n_g7=0\n_g8=0\n_g9=25\n_g10=131\n_g11=bytearray(b'\\x0b\\x00\\x00')\n_g12=neopixel.NeoPixel(pin15,4)\nnp_rgb_pixels=_g12\n_g13=['c5:1','r','c5,1','r:3']\n_g14='Please connect to Maqueen robot and switch it on.'\ndef _f1(dirL,powerL,dirR,powerR):\n\tglobal _g4;_g4[1]=dirL;_g4[2]=powerL;_g4[3]=dirR;_g4[4]=powerR\n\ttry:i2c.write(16,_g4)\n\texcept:raise RuntimeError(_g14)\ndef _f2(side,dir,power):\n\tglobal _g4;_g4[1+side]=dir;_g4[2+side]=power\n\ttry:i2c.write(16,_g4)\n\texcept:raise RuntimeError(_g14)\ndef _f3(speed,offset):return min(_g5[speed]+offset,255)\ndef _f4(r):\n\tB=int(r*100);A=_g1\n\tif A<25:A=25\n\tH=min(abs(A-70),20)/20;C=0\n\tif B>5:\n\t\tD=A*(3*_g8-A-9*B+220);E=-14*_g8+A-200+3*A-10*B-290;C=int(D/E)\n\t\tif C<2:C=2 if B>15 else 1\n\tF=_f3(int(C),0);G=_f3(int(A),0);return F,G\ndef calibrate(offset,differential=0,arcScaling=0):global _g7;global _g6;global _g8;_g6=max(min(int(offset),50),-14);_g7=max(min(int(differential),150),-150);_g8=max(min(arcScaling,50),-50);setSpeed(_g1)\ndef setSpeed(speed):\n\tglobal _g1;global _g2;global _g3;_g1=int(min(max(speed,0),100));A=_f3(_g1,_g6);B=round((1-_g1/100)*abs(_g7))if _g1>0 else 0;C=round(_g1/100*abs(_g7))\n\tif _g7>0:_g2=A-C;_g3=A+B\n\telse:_g2=A+B;_g3=A-C\ndef resetSpeed():setSpeed(50)\ndef stop():_f1(0,0,0,0)\ndef forward():_f1(0,_g2,0,_g3)\ndef backward():_f1(1,_g2,1,_g3)\ndef left():_f1(1,_g2,0,_g3)\ndef right():_f1(0,_g2,1,_g3)\ndef rightArc(radius):A,B=_f4(radius);_f1(0,B,0,A)\ndef leftArc(radius):A,B=_f4(radius);_f1(0,A,0,B)\nclass Motor:\n\tdef __init__(A,side):A._side=side\n\tdef rotate(B,speed):A=speed;C=int(min(max(abs(A),0),100));D=_f3(C,_g6);E=0 if A>0 else 1;_f2(B._side,E,D)\ndef setServo(servo,angle):\n\tD=angle;A=servo\n\tif A=='P0'or A=='S1':B=pin0\n\telif A=='P1'or A=='S2':B=pin1\n\telif A=='P2':B=pin2\n\telse:raise ValueError(\"Unknown Servo. Please use 'P0', 'P1' or 'P2'.\")\n\tif D<0 or D>180:raise ValueError('Invalid angle. Must be between 0 and 180')\n\tC=(_g10-_g9)*int(D);E=(C>>8)+(C>>10)+(C>>11)+(C>>12);F=_g9+E;B.set_analog_period(20);B.write_analog(F)\ndef setMinAngleVal(duty):global _g9;_g9=int(duty)\ndef setMaxAngleVal(duty):global _g10;_g10=int(duty)\nclass IRSensor:\n\t_g21=bytes(b'\\x1d')\n\tdef __init__(A,index):A._index=index\n\tdef read_digital(A):\n\t\ttry:i2c.write(16,IRSensor._g21)\n\t\texcept:raise RuntimeError(_g14)\n\t\tB=~i2c.read(16,1)[0];return(B&2**A._index)>>A._index\n\tdef read_analog(A):\n\t\ttry:i2c.write(16,IRSensor._g21)\n\t\texcept:raise RuntimeError(_g14)\n\t\tB=i2c.read(16,11);return B[1+A._index*2]\ndef ir_read_values_as_byte():i2c.write(16,bytearray([29]));A=i2c.read(16,1);return~A[0]\ndef getDistance():pin13.write_digital(1);pin13.write_digital(0);A=machine.time_pulse_us(pin14,1,50000);B=(A>>6)+(A>>10)+(A>>11)+(A>>12)+1;return max(min(B,500),0)if B>0 else 255\ndef setLED(state,stateR=None):B=state;A=stateR;global _g11;A=A if A!=None else B;_g11[1]=B;_g11[2]=A;i2c.write(16,_g11)\ndef setLEDLeft(state):global _g11;_g11[1]=state;i2c.write(16,_g11)\ndef setLEDRight(state):global _g11;_g11[2]=state;i2c.write(16,_g11)\ndef fillRGB(red,green,blue):\n\tfor A in range(4):_g12[A]=red,green,blue\n\t_g12.show()\nsetRGB=fillRGB\ndef clearRGB():_g12.clear()\ndef posRGB(position,red,green,blue):\n\tA=position\n\tif A<0 or A>3:raise ValueError('invalid RGB-LED position. Must be 0,1,2 or 3.')\n\t_g12[A]=red,green,blue;_g12.show()\ndef setAlarm(state):\n\tif state:music.play(_g13,wait=False,loop=True)\n\telse:music.stop()\ndef beep():music.pitch(440,200,wait=False)\nclass LEDState:ON=1;OFF=0;RED=1\nclass IR:R2=0;R1=1;M=2;L1=3;L2=4;masks=[1,2,4,8,16]\npin2.set_pull(pin2.NO_PULL)\ndelay=sleep\nirR2=IRSensor(0)\nirR1=IRSensor(1)\nirRight=irR1\nirM=IRSensor(2)\nirL1=IRSensor(3)\nirLeft=irL1\nirL2=IRSensor(4)\nmotL=Motor(0)\nmotR=Motor(2)"
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"huskylens": "# For Huskylens (PRO inclusive) with Firmware version 0.5.1Norm or 0.5.3Alpha1.\nfrom microbit import i2c, sleep, running_time\nimport math\n\n_algorithm_names = [\"FaceRecognition\", \n \"ObjectTracking\", \n \"ObjectRecognition\", \n \"LineTracking\", \n \"ColorRecognition\", \n \"TagRecognition\", \n \"ObjectClassification\",\n \"QRRecognition\",\n \"BarcodeRecognition\"]\n\nclass Request_Command:\n # \"\"\"Command Codes that can be sent to the Huskylens.\"\"\"\"\n KNOCK = 0x2C\n ALGORITHM = 0x2D\n ALL = 0x20\n BLOCKS = 0x21\n BLOCKS_LEARNED = 0x24\n BLOCKS_OF_ID = 0x27\n ARROWS = 0x22\n ARROWS_LEARNED = 0x25\n ARROWS_OF_ID = 0x28\n LEARNED = 0x23\n ALL_OF_ID = 0x26\n LEARN = 0x36\n FORGET = 0x37\n CUSTOM_LABEL = 0x2F\n CUSTOM_TEXT = 0x34\n CLEAR_TEXT = 0x35\n SAVE_MODEL = 0x32\n LOAD_MODEL = 0x33\n SAVE_PHOTO = 0x30\n SAVE_SCREENSHOT = 0x39\n IS_PRO = 0x3B\n VERSION = 0x3C\n\nclass Return_Code:\n # \"\"\"Return codes that identify answer types, received from the Huskylens.\"\"\"\n ANY = 0x01 # custom command for \"don't care\", never returned by Huskylens\n OK = 0x2E\n BUSY = 0x3D\n INFO = 0x29\n BLOCK = 0x2A\n ARROW = 0x2B\n IS_PRO = 0x3B\n NEED_PRO = 0x3E\n\nclass Algorithm:\n FACE_RECOGNITION = 0\n OBJECT_TRACKING = 1\n OBJECT_RECOGNITION = 2\n LINE_TRACKING = 3\n COLOR_RECOGNITION = 4\n TAG_RECOGNITION = 5\n OBJECT_CLASSIFICATION = 6\n QR_RECOGNITION = 7\n BARCODE_RECOGNITION = 8\n\nclass Block:\n # \"\"\"Create a new Block with (x,y) as its center and (width,height) as its extent. Id is learned id on Huskylens.\n # Blocks are returned by all Algorithms except for Line_Recognition. \"\"\"\n def __init__(self, x, y, width, height, id):\n self.x = x\n self.y = y\n self.width = width\n self.height = height\n self.id = id\n \n def __str__(self):\n return \"Block: ID_\" + str(self.id) + \" Pos: (\" + str(self.x) + \" \" + str(self.y) + \") Size: (\" + str(self.width) + \" \" + str(self.height) + \")\"\n \nclass Arrow:\n # \"\"\"Create a new Arrow from (x,y)_tail to (x,y)_head. Id is learned id on Huskylens.\n # Arrows are returned only for the Line Recognition Algorithm. \"\"\"\n def __init__(self, x_tail, y_tail, x_head, y_head, id):\n self.x_tail = x_tail\n self.y_tail = y_tail\n self.x_head = x_head\n self.y_head = y_head\n self.id = id\n \n def get_direction(self):\n dx = self.x_head - self.x_tail\n dy = self.y_head - self.y_tail\n deg = 90 - math.degrees(math.atan2(dy, dx))\n if deg < 0: deg = deg + 360\n return int(deg)\n\n def __str__(self):\n return \"Arrow: ID_\" + str(self.id) + \" (\" + str(self.x_tail) + \" \" + str(self.y_tail) + \")->(\" + str(self.x_head) + \" \" + str(self.y_head) + \")\" \n\ndef byte_checksum(byte_list):\n # \"\"\"Computes the checksum and returns the low byte of the sum.\"\"\"\n return sum(byte_list) & 0xFF\n\ndef hexify(byte_array):\n # \"\"\"Takes arraylike of bytes and converts it to hex string for pretty-printing.\"\"\"\n if len(byte_array) == 0: return \"\"\n return \"0x\" + \"\".join(\"{:02x}\".format(i) for i in byte_array)\n\nclass Huskylens:\n\n I2C_ADDR = 0x32\n\n def __init__(self):\n # \"\"\"Create a new Huskylens instance.\n # \n # A Huskylens instance is necessary for further communication.\n # \n # The Huskylens has its own internal state that can't be known by this instance if \n # a Huskylens is operated manually or has data stored in advance (names, learned id's).\n # \"\"\"\n self.learned_slot_count = 0\n self.id_slots = {} # id to learning-slots.\n self.id_names = {} # id to string\n self.algorithm = Algorithm.OBJECT_TRACKING\n self.clear_texts()\n self.pro_enabled = self.is_pro()\n\n def initialize(self):\n # \"\"\"Establishes Connection to Huskylens. Then clears custom Texts and activates Algorithm Object Tracking.\n \n # First, knocks at most 5 times to setup connection.\n # If successful, clears custom text and changes Algorithm to OBJECT_TRACKING.\n # Learned ids and labels are kept from previous uses if available.\n # \n # Returns:\n # bool: Wheter initialization was successfull.\n # \"\"\"\n success = False\n for i in range(5):\n self.knock()\n success, _ = self.get_response(Return_Code.OK)\n if success:\n break\n \n if success > 0:\n s = self.clear_texts()\n s2 = self.set_algorithm(Algorithm.OBJECT_TRACKING)\n if s and s2:\n print(\"Initialization successful!\")\n return True\n else:\n print(\"Initialization Failed. Couldn't change Algorithm\")\n return False\n else:\n print(\"Initialization Failed. Please check connection to Huskylens.\")\n return False\n\n # Low Level communication commands (deal with byte-data yourself)\n\n def send_request(self, command, data=None):\n # \"\"\"Request an action from the Huskylens through a command code and optional Data Bytes.\n # \n # Parameters:\n # command (byte): a Request_Command byte to be sent.\n # data (list of bytes | None): Optional data to attach to the request or None.\n # \"\"\"\n buffer = bytearray(b'\\x55\\xAA\\x11\\x00\\x00')\n buffer[3] = 0 if data is None else len(data)\n buffer[4] = command\n if data:\n for b in data:\n buffer.append(b)\n buffer.append(byte_checksum(buffer))\n # print(\"request:\", hexify(buffer))\n i2c.write(Huskylens.I2C_ADDR, buffer)\n sleep(50)\n\n def get_response(self, return_code=Return_Code.ANY, timeout=500):\n # \"\"\"Read a response from I2C. Returns after a timeout when no data available.\n # If a specific return code is expected and given as a parameter, all other results will set the returned code to 0.\n # If a timeout occured, the return code is set to -1. Other errors return -2.\n # This way, the return code is positive upon success, and negative or 0 otherwise.\n # \n # Parameters:\n # return_code (byte): Optional expected return code.\n # timeout (int): milliseconds to wait for response before giving up\n # \n # Returns:\n # (code | error, data list): A tuple containing the return code or the error code as a signed byte in the first part\n # The data as a list of bytes in the second argument or an empty list if nothing was sent along. \n # \"\"\"\n response_header = bytearray(b\"\\x55\\0\\0\\0\\0\")\n start_time = running_time()\n\n # bytewise polling, as there seem to be unpredictable 0 bytes between messages!\n #response_header = i2c.read(Huskylens.I2C_ADDR, 5, True)\n while running_time() - start_time < timeout:\n byte = i2c.read(Huskylens.I2C_ADDR, 1)[0]\n if byte == 0x55:\n break\n if byte != 0x55:\n return -1, [] # Timeout error \n \n # reading rest of header data\n for i in range(4):\n response_header[i+1] = i2c.read(Huskylens.I2C_ADDR, 1)[0]\n\n if response_header[0:3] != b'\\x55\\xAA\\x11':\n return -2, [] # Wrong header structure error\n \n data_length = response_header[3]\n response_type = response_header[4]\n \n data = []\n if data_length > 0:\n response_body = i2c.read(Huskylens.I2C_ADDR, data_length+1)\n data = response_body[0:-1]\n response_checksum = response_body[-1]\n else:\n response_checksum = ord(i2c.read(Huskylens.I2C_ADDR, 1))\n if response_checksum != byte_checksum(list(response_header) + data):\n return -3, [] # Checksum Error\n \n # print(\"response: \" + hexify([response_type]) + \" \" + hexify(data))\n if return_code == Return_Code.ANY or response_type == return_code:\n return response_type, data\n else:\n return 0, data # not expected answer Hint\n\n def knock(self):\n self.send_request(Request_Command.KNOCK)\n\n # High level commands for students\n\n def set_algorithm(self, algorithm):\n # \"\"\" Change the active algorithm on the Huskylens. Returns True on success.\"\"\"\n if (algorithm == Algorithm.QR_RECOGNITION or algorithm == Algorithm.BARCODE_RECOGNITION) and (not self.pro_enabled):\n raise RuntimeError(\"Error: Huskylens PRO version is required for algorithm \", _algorithm_names[algorithm])\n return False\n data = [algorithm, 0x00]\n self.send_request(Request_Command.ALGORITHM, data)\n success, _ = self.get_response(Return_Code.OK)\n if success > 0:\n print(\"Current Algorithm:\", _algorithm_names[algorithm])\n self.algorithm = algorithm\n return True if success > 0 else False\n\n def get_all(self):\n # \"\"\"Get All detected objects, Blocks or Arrows as a list.\"\"\"\n return self._get_results(Request_Command.ALL)\n\n def get_all_learned(self):\n # \"\"\"Get all detected objects that are learned as a list.\"\"\"\n return self._get_results(Request_Command.LEARNED)\n\n def get_all_with_id(self, id):\n # \"\"\"Get all detected objects with specific id as a list.\"\"\"\n if id <= 0 or id > 255:\n raise RuntimeError(\"Error: ID must be in range from 1 to 255.\")\n return self._get_results(Request_Command.ALL_OF_ID, id)\n\n def get_one(self):\n # \"\"\"Get one instance of centermost detected object (Block or Arrow) else None.\"\"\"\n results = self._get_results(Request_Command.ALL)\n return self._get_centermost(results) \n\n def get_one_learned(self):\n # \"\"\"Get one instance of centermost detected object that has an id > 0. else None.\"\"\"\n results = self._get_results(Request_Command.LEARNED)\n return self._get_centermost(results)\n\n def get_one_with_id(self, id):\n # \"\"\"Get one instance of centermost detected object that has given id. else None.\"\"\"\n if id <= 0 or id > 255:\n raise RuntimeError(\"Error: ID must be in range from 1 to 255.\")\n results = self._get_results(Request_Command.ALL_OF_ID, id)\n return self._get_centermost(results)\n\n def attach_label(self, id, name):\n # \"\"\"Attach the label \"name\" to a learned id of current Algorithm. Returns True on success.\"\"\"\n if self.algorithm == Algorithm.OBJECT_TRACKING or \\\n self.algorithm == Algorithm.LINE_TRACKING: # single learn algorithms\n success = self._set_name(1, name)\n elif self.algorithm == Algorithm.FACE_RECOGNITION or \\\n self.algorithm == Algorithm.TAG_RECOGNITION or \\\n self.algorithm == Algorithm.OBJECT_CLASSIFICATION or \\\n self.algorithm == Algorithm.OBJECT_RECOGNITION: # multi learn algorithms\n # avoid naming unlearned id's to avert bugs.\n slots = self.id_slots.get(id)\n if slots == None:\n raise RuntimeError(\"Can't attach a name to an unlearned ID number\")\n\n self.id_names[id] = name\n\n success = True\n for slot in slots:\n s = self._set_name(slot, name)\n success = success and s > 0\n else: # For color recognition (where it works properly!)\n self.id_names[id] = name\n success = self._set_name(id, name)\n return True if success > 0 else False\n\n def clear_labels(self):\n # \"\"\"Deletes all learned label names on Huskylens for the current algorithm.\"\"\"\n self.id_names.clear()\n for i in range(10):\n self._set_name(i, \"\")\n\n def add_text(self, text, position_x, position_y):\n # \"\"\"Add a custom text to the Huskylens screen at a certain screen pixel-position (top left starting point). \n # Text must be less than 20 bytes long and within pixel-borders. \n # Multiple texts at the same location get overwritten. Returns True on success.\"\"\"\n text_bytes = bytes(text, \"utf-8\")\n if len(text_bytes) > 19:\n raise RuntimeError(\"Custom Text must be less than 20 bytes long.\")\n if position_x > 300 or position_x < 0 or position_y < 35 or position_y > 240:\n raise RuntimeError(\"Custom Text can't be placed outside of screen pixel size.\")\n data = [len(text_bytes)]\n data.append(0xFF if position_x > 255 else 0x00)\n data.append(position_x % 255)\n data.append(240 - position_y) # reverse flipped y axis\n data.extend(list(text_bytes))\n self.send_request(Request_Command.CUSTOM_TEXT, data)\n success, _ = self.get_response(Return_Code.OK)\n return True if success > 0 else False\n \n def clear_texts(self):\n # \"\"\"Deletes all text on the Huskylens screen.\"\"\"\n self.send_request(Request_Command.CLEAR_TEXT)\n success, _ = self.get_response(Return_Code.OK)\n return True if success > 0 else False\n\n def learn(self, id, name=None):\n # \"\"\"Learn and assign an id to the object currently centered on the huskylens camera. \n # Optionally attach label to this learned id. Returns True on success.\"\"\"\n if id <= 0 or id > 255:\n raise RuntimeError(\"Parameter ID for learned item must be in range [0,255]\")\n if self.algorithm == Algorithm.OBJECT_TRACKING or self.algorithm == Algorithm.LINE_TRACKING:\n id = 1\n timeout = 500\n if self.algorithm == Algorithm.OBJECT_CLASSIFICATION:\n timeout = 1000\n self.send_request(Request_Command.LEARN, [id, 0x00])\n success, _ = self.get_response(Return_Code.OK, timeout)\n if success > 0:\n # 1. remember slot for id\n self.learned_slot_count += 1\n if (not (id in self.id_slots)):\n self.id_slots[id] = [self.learned_slot_count]\n else:\n self.id_slots[id].append(self.learned_slot_count)\n # 2. attach, name if available.\n known_by = self.id_names.get(id)\n if known_by != None:\n success = self.attach_label(self.learned_slot_count, known_by)\n elif name != None:\n success = self.attach_label(id, name)\n return True if success > 0 else False\n \n def forget(self):\n # \"\"\"Forget all learned objects (ids) of the current algorithm. \n # Labels are unaffected. Returns True on success.\"\"\"\n self.send_request(Request_Command.FORGET)\n success, _ = self.get_response(Return_Code.OK)\n if success:\n self.learned_slot_count = 0\n self.id_slots.clear()\n return True if success else False\n \n\n def save_photo(self):\n # \"\"\"Save a photo to the SD-Card. No Feedback, fails on Huskylens screen if no SD-Card is available.\"\"\"\n self.send_request(Request_Command.SAVE_PHOTO)\n success, _ = self.get_response(Return_Code.OK, 1000)\n return True if success > 0 else False\n\n def save_screenshot(self):\n # \"\"\"Save a screenshot (including texts) to the SD-Card. No Feedback, fails on Huskylens screen if no SD-Card is available.\"\"\"\n self.send_request(Request_Command.SAVE_SCREENSHOT)\n success, _ = self.get_response(Return_Code.OK, 1000)\n return True if success > 0 else False\n\n def save_model(self, model_id):\n # \"\"\"Save the learned ids and labels to the SD-Card. No Feedback, see Huskylens screen for Result.\n # There can be at most 5 models per Algorithm, indexed by model_id.\"\"\"\n if model_id < 0 or model_id > 4:\n raise RuntimeError(\"Invalid model_id. Must be number in range [0,4]\")\n self.send_request(Request_Command.SAVE_MODEL, [model_id, 0x00])\n success, _ = self.get_response(Return_Code.OK, 1000)\n print(\"Model saving: Check Huskylens screen for Result!\\n\\tModel name:\", _algorithm_names[self.algorithm] + \"_Backup_\" + str(model_id) + \".conf\")\n return True if success > 0 else False\n\n def load_model(self, model_id):\n # \"\"\"Load a previously saved model for the active Algorithm from the SD-Card. No Feedback, see Huskylens screen for Result.\"\"\"\n if model_id < 0 or model_id > 4:\n raise RuntimeError(\"Invalid model_id. Must be number in range [0,4]\")\n self.send_request(Request_Command.LOAD_MODEL, [model_id, 0x00])\n success, _ = self.get_response(Return_Code.OK, 1000)\n print(\"Model Loading: Check Huskylens screen for Result!\")\n return True if success > 0 else False\n\n def is_pro(self):\n # \"\"\"Checks wheter the Huskylens is the PRO version, which supports QR_RECOGNITION and BARCODE_RECOGNITION.\n # Returns True/False on success, else 0.\"\"\"\n self.send_request(Request_Command.IS_PRO)\n success, data = self.get_response(Return_Code.IS_PRO)\n return bool(data[0]) if success > 0 else False\n\n # hidden Utility functions\n\n def _set_name(self, id, name):\n # \"\"\"Set the name of block \"id\" to the given \"name\". Name must be less than 20 characters long.\"\"\"\n name_bytes = bytes(name, \"utf-8\")\n if len(name_bytes) > 19: raise RuntimeError(\"Custom Name must be less than 20 bytes long.\")\n data = [id, len(name_bytes)+1]\n data.extend(list(name_bytes))\n data.append(0x00)\n self.send_request(Request_Command.CUSTOM_LABEL, data)\n success, _ = self.get_response(Return_Code.OK)\n return True if success > 0 else False\n\n def _get_results(self, request_command, id=-1):\n # \"\"\"Get all detected Blocks or Arrows from the Huskylens, specified by the request and id.\n # Possible Requests: BLOCKS, BLOCKS_LEARNED, BLOCKS_OF_ID, ARROWS, ...\n # Returns a list of all the detected Block or Arrow instances.\n # \"\"\"\n request_data = None if id < 0 else [id, 0]\n self.send_request(request_command, request_data)\n\n # 1. get info header\n success, info = self.get_response(Return_Code.INFO)\n if not success:\n raise RuntimeError(\"Failed to request results. Got answer:\" + str(success))\n \n # Ignoring number of detected id's and current frame number.\n n_elements = info[0] + info[1]*255\n #n_ids = info[2] + info[3]*255\n # frame = info[4] + info[5]*255\n #print(\"result info:\", n_elements, n_ids, frame)\n\n # 2. receive data\n el = 0\n objects = []\n\n while el < n_elements:\n response_type, el_data = self.get_response(Return_Code.ANY)\n if response_type == Return_Code.BLOCK and self.algorithm != 3:\n x = el_data[0] + el_data[1]*255\n y = 240 - el_data[2] + el_data[3]*255 # flipped y axis\n width = el_data[4] + el_data[5]*255\n height = el_data[6] + el_data[7]*255\n el_id = el_data[8]\n block = Block(x, y, width, height, el_id)\n objects.append(block)\n el += 1\n \n elif response_type == Return_Code.ARROW:\n xtail = el_data[0] + el_data[1]*255\n ytail = 240 - el_data[2] + el_data[3]*255 # flipped y axis\n xhead = el_data[4] + el_data[5]*255\n yhead = 240 - el_data[6] + el_data[7]*255 # flipped y axis\n el_id = el_data[8]\n arrow = Arrow(xtail,ytail,xhead,yhead,el_id)\n objects.append(arrow)\n el += 1\n elif response_type == 0:\n return [] # Error (couldn't read all detected elements) fail silently.\n return objects\n\n def _get_centermost(self, results):\n # \"\"\"Select and Return the most centered (L1-distance) instance of all detected Objects in \"results\". \"\"\"\n centermost = None\n max_offset = 320+120\n for obj in results:\n center_offset = 0\n if self.algorithm == Algorithm.LINE_TRACKING:\n center_offset = abs((obj.x_tail + (obj.x_tail - obj.x_head) // 2) - 160) \\\n + abs((obj.y_tail + (obj.y_tail - obj.y_head) // 2) - 120)\n else:\n center_offset = abs(obj.x - 160) + abs(obj.y - 120)\n if center_offset < max_offset:\n centermost, max_offset = obj, center_offset\n return centermost \n",
|
|
3
|
+
"mbbitbot": "from microbit import *\nfrom neopixel import *\nfrom utime import ticks_us, sleep_us\n\n\n_v = 200\n_nbLeds = 12\n_np = NeoPixel(pin13, _nbLeds)\n\n_powerDifferential = 0\n_powerOffset = 0\n\n\ndef w(leftforward, leftbackward, rightforward, rightbackward):\n if leftforward > 0 or rightforward > 0:\n pin16.write_analog(leftforward + _powerDifferential)\n pin8.write_analog(leftbackward)\n pin14.write_analog(rightforward - _powerDifferential)\n pin12.write_analog(rightbackward)\n elif leftbackward > 0 or rightbackward > 0:\n pin16.write_analog(leftforward)\n pin8.write_analog(leftbackward + _powerDifferential)\n pin14.write_analog(rightforward)\n pin12.write_analog(rightbackward - _powerDifferential)\n elif leftforward == 0 and rightforward == 0 and leftbackward == 0 and rightbackward == 0:\n pin16.write_analog(0)\n pin8.write_analog(0)\n pin14.write_analog(0)\n pin12.write_analog(0)\n\n\ndef forward():\n w(_v, 0, _v, 0)\n\n\ndef backward():\n w(0, _v, 0, _v)\n\n\ndef stop():\n w(0, 0, 0, 0)\n\n\ndef right():\n w(0, _v, _v, 0)\n\n\ndef left():\n w(_v, 0, 0, _v)\n\n\ndef set_led(pos, red, green, blue):\n _np[pos] = (red, green, blue)\n _np.show()\n\n\ndef fill(red, green, blue):\n for i in range(_nbLeds):\n _np[i] = (red, green, blue)\n _np.show()\n\n\ndef getDistance():\n pin15.write_digital(1)\n sleep_us(10)\n pin15.write_digital(0)\n pin15.set_pull(pin15.NO_PULL)\n while pin15.read_digital() == 0:\n pass\n start = ticks_us()\n while pin15.read_digital() == 1:\n pass\n end = ticks_us()\n echo = end-start\n distance = int(0.01715 * echo)\n return distance\n\n\ndef calibrate(offset, differential=0):\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n\n _powerOffset = max(min(int(offset), 50), -50)\n _powerDifferential = max(min(int(differential), 50), -50)\n _arcScaling = max(min(arcScaling, 50), -50)\n setSpeed(_v / 1023 * 100)\n\n\ndef setSpeed(percent):\n global _v\n speed = percent / 100 * 1023\n speed += _powerOffset/100 * 1023\n speed = min(max(speed, 0), 1023)\n _v = speed\n\n\ndef getLine(bit):\n mask = 1 << bit\n value = 0\n try:\n value = i2c.read(0x1c, 1)[0]\n except OSError:\n pass\n if (value & mask) > 0:\n return 1\n else:\n return 0\n\n\ndef getLight(index):\n if index == 0:\n return pin1.read_analog()\n elif index == 1:\n return pin2.read_analog()\n\n\ndef leftArc(radius):\n speed = _v\n inner_wheel_speed = speed * (radius / (radius + 1))\n w(inner_wheel_speed, 0, speed, 0)\n\n\ndef rightArc(radius):\n speed = _v\n inner_wheel_speed = speed * (radius / (radius + 1))\n w(speed, 0, inner_wheel_speed, 0)\n",
|
|
4
|
+
"mbwait": "from microbit import button_a, button_b, pin0, pin1, pin2, pin_logo, sleep\n\n# choose the reactivity of the press/touch sensing in ms. Default 100ms is 10 checks per second.\nPOLLING_DELAY = 100\n\n# Let the microbit wait until a certain button of choice was pressed (and released).\n\n\ndef wait_for_press(button='any'):\n button_a.was_pressed()\n button_b.was_pressed()\n # busy wait until a chosen button was pressed.\n if button == 'a' or button == 'A':\n while not button_a.was_pressed():\n sleep(POLLING_DELAY)\n elif button == 'b' or button == 'B':\n while not button_b.was_pressed():\n sleep(POLLING_DELAY)\n elif button == 'any' or button == 'ANY':\n while (not button_a.was_pressed()) and (not button_b.was_pressed()):\n sleep(POLLING_DELAY)\n elif button == 'both' or button == 'ab' or button == 'AB':\n while not (button_a.is_pressed() and button_b.is_pressed()):\n sleep(POLLING_DELAY)\n while button_a.is_pressed() or button_b.is_pressed():\n sleep(POLLING_DELAY)\n else:\n raise RuntimeError(\n \"Button to wait for must be either: 'a', 'b', 'any' or 'both'.\")\n\n# Let the microbit wait until a certain touch-sensitive pin of choice is touched.\n\n\ndef wait_for_touch(pin='logo'):\n # busy wait until a given pin/logo is pressed.\n p = pin_logo\n if pin == 'pin0':\n p = pin0\n elif pin == 'pin1':\n p = pin1\n elif pin == 'pin2':\n p = pin2\n elif pin == 'logo' or pin == 'pin_logo' or pin == 'pinLogo':\n p = pin_logo\n else:\n raise RuntimeError(\n \"Argument 'pin' must be one of: 'pin_logo', 'pin0', 'pin1' or 'pin2'.\")\n p.set_touch_mode(p.CAPACITIVE)\n while not p.is_touched():\n sleep(POLLING_DELAY)\n",
|
|
5
|
+
"mbled": "from neopixel import *\nimport gc\nfrom microbit import pin2\n\n\n_nbLeds = 24\n_np = NeoPixel(pin2, _nbLeds)\n\n# Fill all pixels with the same color.\n# The color is specified by giving values between 0 and 255 for red, green and blue\n\n\ndef fill(red, green, blue):\n for i in range(_nbLeds):\n _np[i] = (red, green, blue)\n _np.show()\n\n# Set the specified pixel to the specified color.\n# The pixel is specified by a number between 0 and 23.\n# The color is specified by giving values between 0 and 255 for red, green and blue\n\n\ndef set_led(pos, red, green, blue):\n _np[pos] = (red, green, blue)\n _np.show()\n\n# clears all LEDS by turning them off\n\n\ndef clear():\n _np.clear()\n\n# shift the displayed image by as many led-positions as specified in parameter \"amount\".\n# LED strip behaves like a cycle and wraps around when shifting across borders.\n\n\ndef shift_by(amount):\n shifted_copy = [None]*_nbLeds\n for n in range(0, _nbLeds):\n next_i = (n + amount) % _nbLeds\n shifted_copy[n] = _np[next_i]\n for n in range(0, _nbLeds):\n _np[n] = shifted_copy[n]\n _np.show()\n\n# get linearly interpolated colors in RGB space.\n# \"percent\" is the blending distance between the two colors. 0 is first color only, and 100 is second color only.\n\n\ndef lerp_RGB(r1, g1, b1, r2, g2, b2, percent):\n if percent < 0.0 or percent > 100.0:\n raise RuntimeError(\"Argument 'percent' must be between 0 and 100.\")\n red = max(0, min(255, round(r1 + (r2 - r1) * (percent/100.0))))\n green = max(0, min(255, round(g1 + (g2 - g1) * (percent/100.0))))\n blue = max(0, min(255, round(b1 + (b2 - b1) * (percent/100.0))))\n return red, green, blue\n",
|
|
6
|
+
"mbrobot_plus": "# mbrobot_plus.py\n# Version 1.4 (1.10.2022)\n \nfrom microbit import i2c,pin0,pin1,pin2,sleep\nimport machine\nimport gc\nimport music\n\n_v = 50\n_axe = 0.082\n \ndef w(d1, d2, s1, s2):\n try:\n i2c.write(0x10, bytearray([0x00,d1, d2, s1, s2]))\n except:\n print(\"Please switch on mbRobot!\")\n \ndef setSpeed(speed):\n global _v\n if speed < 30 and speed != 0:\n setPID(1)\n _v = speed + 30 \n elif speed >= 30 and speed < 32:\n setPID(0)\n _v = speed + 2\n else:\n setPID(0)\n _v = speed \n \ndef setPID(pd):\n i2c.write(0x10, bytearray([0x0A, pd]))\n\ndef stop():\n setPID(0)\n w(0, 0, 0, 0) \n \ndef resetSpeed():\n setPID(0)\n _v = 50 \n\ndef forward():\n w(1, _v, 1, _v)\n \ndef backward():\n w(2, _v, 2, _v) \n \ndef left():\n m = 1.825 -0.0175 * _v\n w(2, int(_v * m), 1, int(_v * m))\n \ndef right():\n m = 1.825 -0.0175 * _v\n w(1, int(_v * m), 2, int(_v * m))\n \ndef rightArc(r):\n v = abs(_v)\n if r < _axe:\n v1 = 0\n else:\n f = (r - _axe) / (r + _axe) * (1 - v * v / 200000) \n v1 = int(f * v)\n if _v > 0:\n w(1, v, 1, v1)\n else:\n w(2, v1, 2, v)\n\ndef leftArc(r):\n v = abs(_v)\n if r < _axe:\n v1 = 0\n else:\n f = (r - _axe) / (r + _axe) * (1 - v * v / 200000) \n v1 = int(f * v)\n if _v > 0:\n w(1, v1, 1, v)\n else:\n w(2, v, 2, v1) \n\ndef getDistance():\n pin1.write_digital(1)\n pin1.write_digital(0)\n p = machine.time_pulse_us(pin2, 1, 50000)\n cm = int(p / 58.2 - 0.5)\n return cm if cm > 0 else 255 \n\nclass Motor:\n def __init__(self, id):\n self._id = 2 * id\n \n def _w(self, d, s):\n try:\n i2c.write(0x10, bytearray([self._id, d, s]))\n except:\n print(\"Please switch on mbRobot!\")\n while True:\n pass \n\n def rotate(self, s):\n p = abs(s) \n if s > 0:\n self._w(1, p) \n elif s < 0:\n self._w(2, p) \n else: \n self._w(0, 0)\n \nclass LEDState:\n OFF = 0\n RED = 1\n GREEN = 2\n YELLOW = 3\n BLUE = 4\n PINK = 5\n CYAN = 6\n WHITE = 7\n\ndef setLED(state, stateR=None):\n stateR = stateR or state\n i2c.write(0x10, bytearray([0x0B, state, stateR]))\n \ndef setLEDLeft(state):\n i2c.write(0x10, bytearray([0x0B, state])) \n \ndef setLEDRight(state):\n i2c.write(0x10, bytearray([0x0C, state])) \n \ndef setAlarm(on):\n if on:\n music.play(_m, wait = False, loop = True) \n else:\n music.stop() \n \ndef beep():\n music.pitch(2000, 200, wait = False) \n\ndef ir_read_values_as_byte():\n i2c.write(0x10, bytearray([0x1D]))\n buf = i2c.read(0x10, 1)\n return ~buf[0]\n\ndef setServo(S, Angle):\n if S == \"S1\":\n Servo = 0x14\n if S == \"S2\":\n Servo = 0x15\n buf = Servo, Angle\n i2c.write(0x10, bytes(buf))\n\nclass IR:\n L3 = 0\n L2 = 1\n L1 = 2\n R1 = 3\n R2 = 4\n R3 = 5 \n masks = [0x01,0x02,0x04,0x08,0x10,0x20]\n \nclass IRSensor:\n def __init__(self, index):\n self.index = index\n \n def read_digital(self):\n byte = ir_read_values_as_byte()\n return (byte & IR.masks[self.index]) >> self.index\n\nirLeft = IRSensor(IR.L1)\nirRight = IRSensor(IR.R1)\nirL1 = IRSensor(IR.L1)\nirR1 = IRSensor(IR.R1)\nirL2 = IRSensor(IR.L2)\nirR2 = IRSensor(IR.R2)\nirL3 = IRSensor(IR.L3)\nirR3 = IRSensor(IR.R3)\npin2.set_pull(pin2.NO_PULL)\nmotL = Motor(0)\nmotR = Motor(1)\ndelay = sleep\n_m = ['c6:1', 'r', 'c6,1', 'r', 'r', 'r']\n\n",
|
|
7
|
+
"mbrobot": "# mbrobot.py\n# Date 10/09/24\n\nfrom microbit import i2c, pin1, pin2, pin8, pin12, pin13, pin14, pin15, sleep\nimport gc\nimport machine\nimport music\nimport neopixel\n\n# Motor state\n_speedPercent = 50\n_powerByteL = 40\n_powerByteR = 40\n_motorState = bytearray(5)\n_servoBytes = bytearray(2)\n_powerBytesLUT = bytes(b'\\x00\\x0b\\x0b\\x0c\\x0c\\x0d\\x0d\\x0d\\x0e\\x0e\\x0f\\x0f\\x0f\\x10\\x10\\x11\\x11\\x11\\x12\\x12\\x13\\x13\\x13\\x14\\x14\\x15\\x15\\x15\\x16\\x16\\x17\\x17\\x17\\x18\\x19\\x1a\\x1b\\x1b\\x1c\\x1d\\x1e\\x1f\\x20\\x21\\x22\\x23\\x23\\x24\\x25\\x26\\x27\\x28\\x29\\x2a\\x2b\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x36\\x38\\x3a\\x3c\\x3f\\x41\\x44\\x46\\x49\\x4c\\x4f\\x53\\x56\\x5a\\x5e\\x62\\x67\\x6b\\x70\\x75\\x7b\\x81\\x87\\x8d\\x94\\x9b\\xa3\\xab\\xb4\\xbd\\xc6\\xd0\\xdb\\xe6\\xf2\\xff')\n\n# Calibration data\n_powerOffset = 0\n_powerDifferential = 0\n_arcScaling = 0\n\n# signaling objects\n_underglowNP = neopixel.NeoPixel(pin15, 4)\nnp_rgb_pixels = _underglowNP\n_alarmSequence = ['c5:1', 'r', 'c5:1', 'r:3']\n\n_UNCONNECTEDERRORMSG = \"Please connect to Maqueen robot and switch it on.\"\n\n# Utility functions\n\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n # \"\"\"Write Motor State via i2c\n\n # Parameters:\n # dirL (0/1): Direction of left Wheel. 0=forward, 1=backward\n # powerL (int): Power of left Wheel in range [0,255].\n # dirR (0/1): Direction of right Wheel. 0=forward, 1=backward\n # powerR (int): Power of right Wheel in range [0,255].\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n global _motorState\n _motorState[1] = dirL\n _motorState[2] = powerL\n _motorState[3] = dirR\n _motorState[4] = powerR\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\n\ndef _setSingleMotor(side, dir, power):\n # \"\"\"Write Motor State of a single Motor via i2c\n\n # Parameters:\n # side (0/2): Selection of the Wheel. 0=left, 2=right\n # dir (0/1): Direction for that Wheel. 0=forward, 1=backward\n # power (int): Power for that Wheel in range [0,255].\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n global _motorState\n _motorState[1 + side] = dir\n _motorState[2 + side] = power\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\n# _getPowerByte was used to create LookUpTable (_powerBytesLUT) used in _getPowerByteLUT to reduce Memory Leaks.\n# def _getPowerByte(speed, offset):\n# # \"\"\"Computes the power value for a given speed in %.\n# # It accouts for the nonlinearity of motor strength.\n# # This is the original function that generates the LUT.\n#\n# # Parameter:\n# # speed (number): Desired speed of the Robot in %. Range [0,100].\n# # offset (number): basic power offset to add to the function.\n# # Returns:\n# # int: Power in range [0,255] to write to the motors via i2c.\n# # \"\"\"\n# if speed <= 0:\n# return 0\n# if speed <= 33:\n# return int(0.4 * speed + 11 + offset)\n# elif speed <= 63:\n# return int(0.89 * speed - 5 + offset)\n# elif speed < 100:\n# return int(min(1.0561 ** speed + 20 + offset, 255))\n# else:\n# return 255\n\n\ndef _getPowerByteLUT(speed, offset):\n # \"\"\"Lookup Table version of _getPowerByte\"\"\"\n return min(_powerBytesLUT[speed] + offset, 255)\n\n\ndef _getArcBytes(r):\n # \"\"\"Computes the power bytes to drive an arc.\n\n # Parameter:\n # r (float): Radius in meters of the desired Arc.\n # Measured from the center of the axle.\n # Returns:\n # (int, int): Power byte values for each motor.\n # First the outer Wheels byte [0,255],\n # then the inner Wheels byte [0,255].\n # \"\"\"\n outerSpeed = _speedPercent\n rCm = int(r * 100) # r in cm instead of meters\n # adjust outer speed for unhealthy combinations\n # That is: too low speeds and big arcs.\n threshold = outerSpeed - max(rCm + 20, 40)\n if threshold <= 0:\n outerSpeed = min(max(rCm + 40, 40), 100)\n reducedSpeed = 0\n if rCm >= 4: # minimal radius is half the axle size: 3.5 cm rounded.\n flattening = (100 - outerSpeed) // 2\n reducedSpeed = (rCm * 10 - 35) / \\\n (rCm * (11 + (_arcScaling-4)/10) + 90 + flattening)\n reducedSpeed = reducedSpeed * outerSpeed\n innerByte = _getPowerByteLUT(int(reducedSpeed), 0)\n outerByte = _getPowerByteLUT(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\n# Movement Functions\n\n\ndef calibrate(offset, differential=0, arcScaling=0):\n # \"\"\"Adjust the driving behaviour of the robots\n\n # Parameters:\n # offset (int): Offsets the minimal power of the motors.\n # Range [-10,50]. Highly affected by battery level.\n # Adjust this value until it starts moving at speed 1%.\n # differential (int, optional): Adjusts power difference\n # of left and right Wheel. Range [-150, 150].\n # Varies unpredictably with different speeds.\n # If a Robot steers left when driving forward: negative value\n # If a Robot steers right when driving forward: positive value\n # Perfectly straight driving Robots can leave this at 0.\n # arcScaling (int, optional): Adjusts the radius\n # driven by leftArc/rightArc. Valid range [-50, 50].\n # If the Robots radius is too large: positive value\n # If the Robots radius is too small: negative value\n # This then adjusts all radii for this Robot, by\n # scaling it's internal function to the new range.\n # \"\"\"\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n _powerOffset = max(min(int(offset), 50), -10)\n _powerDifferential = max(min(int(differential), 150), -150)\n _arcScaling = max(min(arcScaling, 50), -15)\n setSpeed(_speedPercent)\n\n\ndef setSpeed(speed):\n # \"\"\"sets the speed for future motion\n\n # Parameter:\n # speed (int): in Range [0,100] as % of desired velocity.\n # \"\"\"\n global _speedPercent\n global _powerByteL\n global _powerByteR\n _speedPercent = int(min(max(speed, 0), 100))\n powerByte = _getPowerByteLUT(_speedPercent, _powerOffset)\n boost = round((1 - _speedPercent / 100) *\n abs(_powerDifferential)) if _speedPercent > 0 else 0\n reduction = round((_speedPercent / 100) * abs(_powerDifferential))\n if _powerDifferential > 0:\n _powerByteL = powerByte - reduction\n _powerByteR = powerByte + boost\n else:\n _powerByteL = powerByte + boost\n _powerByteR = powerByte - reduction\n\n\ndef resetSpeed():\n setSpeed(50)\n\n\ndef stop():\n _setMotors(0, 0, 0, 0)\n\n\ndef forward():\n _setMotors(0, _powerByteL, 0, _powerByteR)\n\n\ndef backward():\n _setMotors(1, _powerByteL, 1, _powerByteR)\n\n\ndef left():\n _setMotors(1, _powerByteL, 0, _powerByteR)\n\n\ndef right():\n _setMotors(0, _powerByteL, 1, _powerByteR)\n\n\ndef rightArc(radius):\n # \"\"\"radius must be given in meters.\"\"\"\n inner, outer = _getArcBytes(radius)\n _setMotors(0, outer, 0, inner)\n\n\ndef leftArc(radius):\n # \"\"\"radius must be given in meters.\"\"\"\n inner, outer = _getArcBytes(radius)\n _setMotors(0, inner, 0, outer)\n\n\nclass Motor:\n def __init__(self, side):\n # \"\"\"Create a single motor.\n\n # Parameter:\n # side (8/2): 0=left, 2=right\n # \"\"\"\n self._side = side\n\n def rotate(self, speed):\n # \"\"\"Controls rotation of this motor.\n\n # Parameters:\n # speed (int): Desired speed in %.\n # Valid range [-100,100].\n # Negative values are for backward turning.\n # \"\"\"\n speedClamped = int(min(max(abs(speed), 0), 100))\n power = _getPowerByteLUT(speedClamped, _powerOffset)\n direction = 0 if speed > 0 else 1\n _setSingleMotor(self._side, direction, power)\n\n\ndef setServo(servo, angle):\n # \"\"\"Moves the Servo to position angle.\n # Servos must be connected to the Maqueen Lite's Servo connectors.\n # They are located in front of the left wheel.\n\n # Parameters:\n # servo (str): Desired Servo Port. Either 'S1' or 'S2'.\n # angle (int): Desired angle in degrees. Range [0,180].\n\n # raises:\n # ValueError: if arguments are out of valid range\n # RuntimeError: if Robot is switched off or unconnected.\n # \"\"\"\n global _servoBytes\n # Acceptance of \"P0\" and \"P1\" is for compatibility with V2.\n if servo == 'S1' or servo == 'P0':\n _servoBytes[0] = 0x14\n elif servo == 'S2' or servo == 'P1':\n _servoBytes[0] = 0x15\n else:\n raise ValueError(\"Unknown Servo. Please use 'S1' or 'S2'.\")\n\n if angle < 0 or angle > 180:\n raise ValueError(\"Invalid angle. Must be between 0 and 180\")\n\n _servoBytes[1] = angle\n try:\n i2c.write(0x10, _servoBytes)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\n# Sensor functions\n\n\nclass IRSensor():\n def __init__(self, pin):\n # \"\"\"Create a new IR sensor.\n\n # Parameter:\n # pin (object): pin13=left, pin14=right\n # \"\"\"\n self._pin = pin\n\n def read_digital(self):\n # \"\"\"Returns if the surface below is dark or bright.\n # Result can be adjusted by putting the sensor on the dark\n # surface and pressing the LineKey calibration button on the\n # Robot for a few seconds, until the LED's blink.\n\n # Returns:\n # 0 if the surface is dark. No light was reflected (in Air).\n # 1 if the surface is bright. A lot of light was reflected.\n # \"\"\"\n return self._pin.read_digital()\n\n def read_analog(self):\n raise NameError(\n \"Maqueen Lite does not support reading analog sensor values.\")\n\n\ndef getDistance():\n # \"\"\"uses the ultrasonic sensor to measure distance\n\n # Returns:\n # int: valid Distance as cm in range [0,500].\n # For measurement errors or larger distances: 255.\n # \"\"\"\n pin1.write_digital(1)\n pin1.write_digital(0)\n p = machine.time_pulse_us(pin2, 1, 50000)\n # approximate division: cm = p / 57.5\n cm = (p >> 6) + (p >> 10) + (p >> 11) + (p >> 12) + 1\n return max(min(cm, 500), 0) if cm > 0 else 255\n\n# Signaling functions\n\n\ndef setLED(state, stateR=None):\n # \"\"\"Set the front red LED's.\n\n # Parameters:\n # state (0/1): Sets the state of the left LED.\n # if stateR is omitted, then both LEDS.\n # 0=Off, 1=On\n # stateR (0/1/None, optional): Sets the right LED state.\n # 0=Off, 1=On, Default=None uses \"state\" for right LED.\n # \"\"\"\n stateR = stateR if stateR != None else state\n pin8.write_digital(state)\n pin12.write_digital(stateR)\n\n\ndef setLEDLeft(state):\n # \"\"\"state: 0=Off, 1=On\"\"\"\n pin8.write_digital(state)\n\n\ndef setLEDRight(state):\n # \"\"\"state: 0=Off, 1=On\"\"\"\n pin12.write_digital(state)\n\n\ndef fillRGB(red, green, blue):\n # \"\"\"Uses Neopixel to set all 4 bottom RGB LEDs color.\n # Parameters (red,green,blue) are each a byte in Range [0,255].\n # \"\"\"\n for i in range(4):\n _underglowNP[i] = (red, green, blue)\n _underglowNP.show()\nsetRGB = fillRGB\n\n\ndef clearRGB():\n _underglowNP.clear()\n\n\ndef posRGB(position, red, green, blue):\n # \"\"\"Uses Neopixel to set a single RGB LED of the robot.\n\n # Parameters:\n # position (int): position of the targeted LED.\n # Numbers are visible at underside of Robot.\n # 0=front left\n # 1=back left\n # 2=back right\n # 3=front right\n # red, green, blue (int): color byte value.\n # each in range [0,255].\n\n # raises:\n # ValueError: if position argument is out of valid range\n # \"\"\"\n if position < 0 or position > 3:\n raise ValueError(\"invalid RGB-LED position. Must be 0,1,2 or 3.\")\n _underglowNP[position] = (red, green, blue)\n _underglowNP.show()\n\n\ndef setAlarm(state):\n # \"\"\"state: 0=Off, 1=On\"\"\"\n if state:\n music.play(_alarmSequence, wait=False, loop=True)\n else:\n music.stop()\n\n\ndef beep():\n music.pitch(440, 200, wait=False)\n\n\n# Default instances\npin2.set_pull(pin2.NO_PULL)\ndelay = sleep\nirLeft = IRSensor(pin13)\nirRight = IRSensor(pin14)\nmotL = Motor(0)\nmotR = Motor(2)\n",
|
|
8
|
+
"mbrobot_plusV3": "# mbrobot_plusV3.py\n# Date 25/11/25\n\nfrom microbit import i2c, sleep, running_time, pin0, pin1, pin2\nimport neopixel\nimport music\n\n_motorState = bytearray(5)\n_speedPercent = 50\n_powerByteL = 50\n_powerByteR = 50\n_powerBytesLUT = bytes(b'\\x00\\x0f\\x10\\x10\\x11\\x12\\x12\\x13\\x13\\x14\\x15\\x15\\x16\\x16\\x17\\x18\\x18\\x19\\x19\\x1a\\x1b\\x1b\\x1c\\x1c\\x1d\\x1e\\x1e\\x1f\\x1f\\x20\\x21\\x21\\x22\\x22\\x23\\x24\\x24\\x25\\x25\\x26\\x27\\x29\\x2a\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x35\\x36\\x37\\x38\\x39\\x3a\\x3b\\x3b\\x3c\\x3e\\x3f\\x41\\x43\\x45\\x47\\x49\\x4b\\x4d\\x50\\x52\\x55\\x58\\x5b\\x5e\\x61\\x65\\x69\\x6d\\x71\\x75\\x7a\\x7f\\x84\\x89\\x8f\\x95\\x9b\\xa2\\xa9\\xb1\\xb9\\xc1\\xca\\xd3\\xdd\\xe8\\xf3\\xff')\n_arcScaling = 0\n_UNCONNECTEDERRORMSG = \"Please connect to Maqueen robot and switch it on.\"\n_underglowNP = neopixel.NeoPixel(pin1, 4)\n_alarmSequence = ['c5:1', 'r', 'c5,1', 'r:3']\n_buff1 = bytearray(1)\n_buff2 = bytearray(2)\n_add_mq = 0x10\n_servoMinPulse=25\n_servoMaxPulse=131\n_lidarMode=8\n\ndef _wr1(reg):\n _buff1[0] = reg\n i2c.write(_add_mq, _buff1)\n\ndef _wr2(reg, val):\n _buff2[0] = reg\n _buff2[1] = val\n i2c.write(_add_mq, _buff2)\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n global _motorState\n _motorState[1] = dirL\n _motorState[2] = powerL\n _motorState[3] = dirR\n _motorState[4] = powerR\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\ndef _setSingleMotor(side, dir, power):\n global _motorState\n _motorState[1 + side] = dir\n _motorState[2 + side] = power\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\ndef setSpeed(speed):\n global _speedPercent\n global _powerByteL\n global _powerByteR\n _speedPercent = int(min(max(speed,0),100))\n _powerByteL = int(round(2.4*speed+14))\n _powerByteR = int(round(2.4*speed+14))\n\ndef resetSpeed():\n setSpeed(50)\n\ndef stop():\n _setMotors(0,0,0,0)\n\ndef forward():\n _setMotors(0, _powerByteL, 0, _powerByteR)\n\ndef backward():\n _setMotors(1, _powerByteL, 1, _powerByteR)\n\ndef left():\n _setMotors(1, _powerByteL, 0, _powerByteR)\n \ndef right():\n _setMotors(0, _powerByteL, 1, _powerByteR)\n\ndef _getPowerByteLUT(speed, offset):\n return min(_powerBytesLUT[speed] + offset, 255)\n\ndef _getArcBytes(r):\n rmm = int(r * 100)\n outerSpeed = _speedPercent\n if outerSpeed < 25:\n outerSpeed = 25\n reducedSpeed = 0\n if rmm > 5:\n n = outerSpeed * (3 * _arcScaling - outerSpeed - 9 * rmm + 220)\n d = -14 * _arcScaling + outerSpeed - 200 + 3 * outerSpeed - 10 * rmm - 290\n reducedSpeed = int(n/d)\n if reducedSpeed < 2:\n reducedSpeed = 2 if rmm > 15 else 1\n innerByte = _getPowerByteLUT(int(reducedSpeed), 0)\n outerByte = _getPowerByteLUT(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\ndef rightArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, outer, 0, inner)\n\n\ndef leftArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, inner, 0, outer)\n\nclass Motor:\n def __init__(self, side):\n self._side = side\n\n def rotate(self, speed):\n speedClamped = int(min(max(abs(speed), 0), 100))\n power = speedClamped\n direction = 0 if speed > 0 else 1\n _setSingleMotor(self._side, direction, power)\n\ndef setServo(servo,angle):\n if angle < 0 or angle >180:\n raise ValueError(\"Invalid angle. Must be between 0 and 180\")\n if servo in [\"P0\", \"S1\"]:\n pin = pin0\n elif servo in [\"P1\", \"S2\"]:\n pin = pin1\n elif servo in [\"P2\", \"S3\"]:\n pin = pin2\n else:\n raise ValueError(\"Valid servo names: S1, S2, S3 or P0, P1, P2\")\n frac = (_servoMaxPulse - _servoMinPulse) * int(angle)\n offset = (frac >> 8)+ (frac >> 10) + (frac >> 11)+ (frac >> 12) # / 180\n usPulseTime = _servoMinPulse + offset \n pin.set_analog_period(20)\n pin.write_analog(usPulseTime)\n\t\t\nclass IRSensor:\n _address = bytes(b'\\x1D') \n\n def __init__(self, index):\n self.index = index\n\n def read_digital(self):\n try:\n i2c.write(0x10, IRSensor._address)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n byte = ~i2c.read(0x10, 1)[0]\n return (byte & (2 ** self.index)) >> self.index\n\n def read_analog(self):\n try:\n _wr1(0x1D)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n buffer = i2c.read(0x10,11)\n return buffer[2+2*self.index] << 8 | buffer[1+2*self.index]\n\ndef setLEDs(rgbl, rgbr):\n _wr2(11, rgbl)\n _wr2(12, rgbr)\n\ndef setLED(state, stateR=None):\n stateR = stateR if stateR != None else state\n setLEDs(state, stateR)\n\t\ndef setLEDLeft(rgbl):\n _wr2(11, rgbl)\n\t\ndef setLEDRight(rgbr):\n _wr2(12, rgbr)\t\n\ndef fillRGB(red, green, blue):\n _underglowNP.clear()\n _underglowNP.fill((red,green,blue))\n _underglowNP.show()\n\t\ndef setRGB(r,g,b):\n fillRGB(r,g,b)\n\t\ndef clearRGB():\n _underglowNP.clear()\n\ndef posRGB(position, red, green, blue):\n if position < 0 or position > 3:\n raise ValueError(\"invalid RGB-LED position. Must be 0,1,2 or 3.\")\n _underglowNP[position] = (red, green, blue)\n _underglowNP.show()\n\ndef setAlarm(state):\n if state:\n music.play(_alarmSequence, wait=False, loop=True) \n else:\n music.stop() \n\ndef beep():\n music.pitch(440, 200, wait=False) \n\ndef readLightIntensity(side):\n _wr1(78)\n LightBuffer = i2c.read(0x10, 4, repeat=False)\n if side == 1:\n\n return LightBuffer[0] << 8 | LightBuffer[1]\n else:\n return LightBuffer[2] << 8 | LightBuffer[3]\n\ndef setPatrolSpeed(speed):\n _wr2(63, speed)\n\ndef setIntersectionRunMode(mode):\n _wr2(69, mode)\n\ndef setTRordRunMode(mode):\n _wr2(70, mode)\n\ndef setLeftOrStraightRunMode(mode):\n _wr2(71, mode)\n\ndef setRightOrStraightRunMode(mode):\n _wr2(72, mode)\n\ndef patrolling(patrol):\n if patrol == 1:\n val = 0x04 | 0x01\n else:\n val = 0x08\n _wr2(60, val)\n \ndef intersectionDetecting():\n _wr1(61)\n data = i2c.read(0x10, 1)[0]\n return data\n\ndef pidControlDistance(dir, distance, interruption):\n speed = 2\n if distance >= 6000:\n distance = 60000\n _wr2(64, dir)\n _wr2(85, speed)\n _wr2(65, distance >> 8)\n _wr2(66, distance)\n _wr2(60, 0x04 | 0x02)\n if (interruption == 1):\n _wr1(0x57)\n flagBuffer = i2c.read(0x10, 1)\n while flagBuffer[0] == 1:\n sleep(10)\n flagBuffer = i2c.read(0x10, 1)\n\ndef pidControlAngle(angle, interruption):\n speed = 2\n if angle >= 0:\n buf = 1\n else:\n buf = 2\n angle = -angle\n _wr2(67, buf)\n _wr2(86, speed)\n _wr2(68, angle)\n _wr2(60, 0x04 | 0x02)\n if interruption == 1:\n _wr1(0x57)\n buff = i2c.read(0x10, 1)\n while buff[0] == 1:\n sleep(10)\n buff = i2c.read(0x10, 1)\n\ndef pidControlStop():\n _wr2(60, 0x10)\n\ndef readRealTimeSpeed(type):\n _wr2(76, 1)\n buff = i2c.read(0x10, 2)\n if type == 1:\n return buff[0] / 5\n else:\n return buff[1] / 5\n\ndef _sendLidarCommand(cmd, args=[]):\n args_len = len(args)\n packet_len = args_len + 1 \n packet = bytearray(4 + args_len) \n packet[0] = 0x55\n packet[1] = (packet_len >> 8) & 0xFF\n packet[2] = packet_len & 0xFF\n packet[3] = cmd\n for i, arg in enumerate(args):\n packet[4 + i] = arg\n # chunkwise sending? TODO\n i2c.write(0x33, packet)\n\ndef _receiveLidarData(expectedCommand):\n TIMEOUT = 1000\n MAX_SIZE = 32\n start_time = running_time()\n success = False\n data = None\n started = False\n\n while running_time() - start_time < TIMEOUT and started == False:\n status = i2c.read(0x33, 1)[0] \n if status == 0x53: \n started = True\n elif status == 0x63: \n return success, data\n sleep(16)\n\n if started == True:\n header = i2c.read(0x33, 3) \n cmd = header[0]\n data_length = header[1] | (header[2] << 8)\n\n if cmd == expectedCommand:\n success = True\n data = bytearray()\n remaining_bytes = data_length\n chunk_size = min(remaining_bytes, MAX_SIZE)\n while running_time() - start_time < TIMEOUT and remaining_bytes > 0:\n try:\n chunk = i2c.read(0x33, chunk_size)\n data.extend(chunk)\n remaining_bytes -= len(chunk)\n except:\n sleep(1)\n return success, data\n\ndef setLidarMode(mode=8):\n global _lidarMode\n if mode not in [4, 8]:\n raise ValueError(\"Lidar mode must be 4 or 8\")\n mode_text = \"4x4\" if mode == 4 else \"8x8\"\n print(\"Switching Lidar Mode to \" + mode_text + \".\\nPlease wait up to 10 seconds.\")\n success = False\n\n for i in range(10):\n _sendLidarCommand(1, [0, 0, 0, mode])\n success, _ = _receiveLidarData(1)\n\n if success == True: break\n sleep(17)\n\n if success:\n _lidarMode = mode\n sleep(5000)\n else:\n raise RuntimeError(\"Failed to switch Lidar Mode\")\n\ndef getDistanceAt(x_pos, y_pos):\n _sendLidarCommand(0x3, [x_pos, y_pos])\n success, data = _receiveLidarData(0x3)\n if success and len(data) >= 2:\n distance = (data[0] | (data[1] << 8)) // 10\n return distance\n else:\n return 1023\n\ndef getDistanceList():\n _sendLidarCommand(0x2)\n success, data = _receiveLidarData(0x2)\n if success and len(data) >= 32:\n distList = []\n for i in range(0,len(data),2):\n d = data[i] | (data[i+1] << 8)\n distList.append(d // 10)\n return distList\n else:\n return []\n\ndef getDistance():\n global _lidarMode\n mid = int(_lidarMode/2)\n topLeft = getDistanceAt(mid-1, mid-1)\n topRight = getDistanceAt(mid, mid-1)\n bottomLeft = getDistanceAt(mid-1, mid)\n bottomRight = getDistanceAt(mid, mid)\n distanceList = [topLeft, topRight, bottomLeft, bottomRight]\n return min(distanceList)\n\n\t\t\ndef getDistanceGrid():\n _sendLidarCommand(0x2)\n success, data = _receiveLidarData(0x2)\n if success and len(data) >= 32:\n distGrid = []\n stride = 16 if len(data) == 128 else 8\n for i in range(0,len(data),stride):\n row = []\n for j in range(0,stride,2):\n d = data[i+j] | (data[i+j+1] << 8)\n row.append(d // 10)\n distGrid.append(row)\n return distGrid\n else:\n return []\n\ndef getDistanceColumn(index):\n _sendLidarCommand(0x5, [index])\n success, data = _receiveLidarData(0x5)\n if success and len(data) >= 8:\n row = []\n for i in range(0, len(data), 2):\n distance = data[i] | (data[i+1] << 8)\n row.append(distance // 10)\n return row\n return []\n\ndef getDistanceRow(index):\n _sendLidarCommand(0x6, [index])\n success, data = _receiveLidarData(0x6)\n if success and len(data) >= 8:\n col = []\n for i in range(0, len(data), 2):\n distance = data[i] | (data[i+1] << 8)\n col.append(distance // 10)\n return col\n return []\n\n \npin2.set_pull(pin2.NO_PULL)\ndelay = sleep\nirR2 = IRSensor(0)\nirR1 = IRSensor(1)\nirRight = irR1\nirM = IRSensor(2)\nirL1 = IRSensor(3)\nirLeft = irL1\nirL2 = IRSensor(4)\nmotL = Motor(0)\nmotR = Motor(2)",
|
|
9
|
+
"mbmarsrover": "from microbit import *\nfrom neopixel import *\nimport utime\n\n_servoArray = [0, 9, 11, 13, 15]\n_servoOffset = [0, 0, 0, 0, 0]\n_initI2C = False\n\n_nbLeds = 4\n_np = NeoPixel(pin2, _nbLeds)\n\n_speedPercent = 50\n_powerByteL = 40\n_powerByteR = 40\n\n_powerOffset = 0\n_powerDifferential = 0\n_arcScaling = 0\n\n_MAX_CM_DISTANCE = 500\n_CM_PER_MICROSECOND = 29.1\n\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n pinsL = (pin1, pin12)\n pinsR = (pin8, pin0)\n\n pinsL[dirL].write_analog(powerL)\n pinsL[1 - dirL].write_analog(0)\n\n pinsR[dirR].write_analog(powerR)\n pinsR[1 - dirR].write_analog(0)\n\n\ndef _setSingleMotor(side, direction, power):\n if side == 0:\n pins = (pin1, pin12)\n elif side == 1:\n pins = (pin8, pin0)\n\n pins[direction].write_analog(power)\n pins[1 - direction].write_analog(0)\n\n\ndef _getArcBytes(r):\n outerSpeed = _speedPercent\n rCm = int(r * 100)\n threshold = outerSpeed - max(rCm + 20, 40)\n if (threshold <= 0):\n outerSpeed = min(max(rCm + 40, 40), 100)\n reducedSpeed = 0\n if rCm >= 4:\n flattening = (100 - outerSpeed) // 2\n reducedSpeed = (rCm * 10 - 35) / \\\n (rCm * (11 + (_arcScaling - 4) / 10) + 90 + flattening)\n reducedSpeed = reducedSpeed * outerSpeed\n innerByte = _convertSpeedToAnalogValue(int(reducedSpeed), 0)\n outerByte = _convertSpeedToAnalogValue(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\n\ndef _initPCA():\n global _initI2C\n _initI2C = True\n i2cData = bytearray(2)\n i2cData[0] = 0\n i2cData[1] = 0x10\n i2c.write(0x40, i2cData)\n\n i2cData[0] = 0xFE\n i2cData[1] = 101\n i2c.write(0x40, i2cData)\n\n i2cData[0] = 0\n i2cData[1] = 0x81\n i2c.write(0x40, i2cData)\n\n\ndef _pulse_in(pin, value, timeout):\n start_time = utime.ticks_us()\n\n while pin.read_digital() != value:\n if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:\n return 0\n\n start_time = utime.ticks_us()\n while pin.read_digital() == value:\n if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:\n return 0\n\n return utime.ticks_diff(utime.ticks_us(), start_time)\n\n\ndef calibrate(offset, differential=0, arcScaling=0):\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n\n _powerOffset = max(min(int(offset), 500), -50)\n _powerDifferential = max(min(int(differential), 150), -150)\n _arcScaling = max(min(arcScaling, 50), -15)\n setSpeed(_speedPercent)\n\n\ndef setSpeed(speed):\n global _speedPercent\n global _powerByteL\n global _powerByteR\n\n _speedPercent = int(min(max(speed, 0), 100))\n powerValue = _convertSpeedToAnalogValue(_speedPercent, _powerOffset)\n boost = round((1 - _speedPercent / 100) *\n abs(_powerDifferential)) if _speedPercent > 0 else 0\n reduction = round((_speedPercent / 100) * abs(_powerDifferential))\n if _powerDifferential > 0:\n _powerByteL = powerValue - reduction\n _powerByteR = powerValue + boost\n else:\n _powerByteL = powerValue + boost\n _powerByteR = powerValue - reduction\n\n\ndef _convertSpeedToAnalogValue(speed, offset):\n analogValue = int(speed * 1023 / 100) + offset\n return min(max(analogValue, 0), 1023)\n\n\ndef stop():\n _setMotors(0, 0, 0, 0)\n\n\ndef forward():\n _setMotors(0, _powerByteL, 0, _powerByteR)\n\n\ndef backward():\n _setMotors(1, _powerByteL, 1, _powerByteR)\n\n\ndef setServo(servoNum, angle):\n global _servoArray, _initI2C\n if _initI2C == False:\n _initPCA()\n offsetNum = servoNum\n servoNum = _servoArray[servoNum]\n i2cData = bytearray(2)\n start = 0\n angle = max(min(angle, 90), -90)\n stop = 396 + (angle + _servoOffset[offsetNum]) * 223 / 90\n i2cData[0] = 0x06 + servoNum * 4 + 2\n i2cData[1] = int(stop) + 0xff\n i2c.write(0x40, i2cData)\n\n i2cData[0] = 0x06 + servoNum*4 + 3\n i2cData[1] = int(stop) >> 8\n i2c.write(0x40, i2cData)\n\n\ndef clearServos():\n setServo(0, 0)\n setServo(1, 0)\n setServo(2, 0)\n setServo(3, 0)\n setServo(4, 0)\n sleep(500)\n\n\ndef steer(angle):\n angle = max(min(angle, 45), -45)\n setServo(1, angle)\n setServo(2, -angle)\n setServo(3, -angle)\n setServo(4, angle)\n sleep(500)\n\n\ndef setLED(pos, red, green, blue):\n _np[pos] = (red, green, blue)\n _np.show()\n\n\ndef fill(red, green, blue):\n for i in range(_nbLeds):\n _np[i] = (red, green, blue)\n _np.show()\n\n\ndef getDistance():\n trig = pin13\n echo = pin13\n\n d = 10\n\n trig.set_pull(trig.NO_PULL)\n\n for _ in range(10):\n trig.write_digital(0)\n utime.sleep_us(2)\n trig.write_digital(1)\n utime.sleep_us(10)\n trig.write_digital(0)\n\n duration = _pulse_in(echo, 1, _MAX_CM_DISTANCE * _CM_PER_MICROSECOND)\n if duration > 0:\n d = duration\n break\n\n return round(d / _CM_PER_MICROSECOND)\n\n\ndef calibrateServo(pos, angleDifferential):\n global _servoOffset\n\n angleDifferential = max(min(angleDifferential, 90), -90)\n _servoOffset[pos] = angleDifferential\n clearServos()\n",
|
|
10
|
+
"mbrobotmot": "# mbrobotmot.py\n# Version 1.2, Aug 9, 2019\n\nimport gc\nfrom microbit import i2c, pin1, pin2, pin8, pin12, pin13, pin14, sleep\nimport machine\n\nclass Motor:\n def __init__(self, id):\n self._id = 2 * id\n\n def rotate(self, s):\n v = abs(s)\n if s > 0:\n self._w(0, v) \n elif s < 0:\n self._w(1, v) \n else: \n self._w(0, 0) \n \n\n def _w(self, d, s):\n try:\n i2c.write(0x10, bytearray([self._id, d, s]))\n except:\n print(\"Please switch on mbRobot!\")\n while True:\n pass\n\ndelay = sleep\n\ndef getDistance():\n pin1.write_digital(1)\n pin1.write_digital(0)\n p = machine.time_pulse_us(pin2, 1, 50000)\n cm = int(p / 58.2 + 0.5)\n return cm if cm > 0 else 255\n\ndef setLED(on):\n pin8.write_digital(on)\n pin12.write_digital(on)\n\npin2.set_pull(pin2.NO_PULL)\nirLeft = pin13\nirRight = pin14\nledLeft = pin8\nledRight = pin12\nmotL = Motor(0)\nmotR = Motor(1)",
|
|
11
|
+
"controller": "# Controller v1.0, Date 21.06.24\n# Enables easy use of the DFRobot Micro:bit GamePad by simulating buttons the same way as the microbit internal ones.\nfrom microbit import run_every, pin13, pin14, pin15, pin16, pin8, pin1, pin2, pin12, button_a, button_b, sleep\n\nclass _Controller_Button:\n #\"\"\" Simulated Button for regular pins with same functionality as the micro:bit buttons a and b.\"\"\"\n \n def __init__(self, pin):\n # \"\"\"create a new simulated button from a digital pin\n\n # Parameter:\n # pin (MicroBitDigitalPin): pin to use as button\n # \"\"\"\n self._pin = pin\n self.previous_state = 0\n self._press_count = 0\n self._pressed_before = False\n pin.set_pull(pin.PULL_UP)\n \n def _update_state(self):\n # \"\"\" internally update the buttons state.\"\"\"\n current_state = 1 - self._pin.read_digital()\n \n if current_state == 1 and self.previous_state == 0: # Low -> High\n self._press_count += 1\n self._pressed_before = True\n \n self.previous_state = current_state\n\n def is_pressed(self):\n # \"\"\" check if the button is currently pressed.\n\n # Returns:\n # bool: if button is currently pressed.\n # \"\"\"\n return False if self._pin.read_digital() else True\n \n def was_pressed(self):\n # \"\"\" check if button was pressed down before. Resets upon call. \n\n # Returns:\n # bool: True if button was pressed down after last call of this function.\n # \"\"\"\n state = self._pressed_before\n self._pressed_before = False\n return state\n \n def get_presses(self):\n # \"\"\" get the amount of button presses since last call.\n \n # Returns:\n # int: number of button (down) presses since last call of this function.\n # \"\"\"\n count = self._press_count\n self._press_count = 0\n return count\n\nclass _Controller_Analog_Stick:\n # \"\"\" class that encapsulates the right analog stick of the controller. \n # This includes the turning in an xy-plane and the pressing (z-button).\"\"\"\n\n def __init__(self, pinX, pinY, pinZ):\n # \"\"\" creates a new analog-stick given its input pins.\n \n # Parameters:\n # pinX (MicroBitAnalogDigitalPin): The pin to use for the x-axis (left-right).\n # pinY (MicroBitAnalogDigitalPin): The pin to use for the y-axis (up-down).\n # pinZ (MicroBitDigitalPin): The pin to use for the z-button.\n # \"\"\"\n self.pin_x = pinX\n self.pin_y = pinY\n self.button_z = _Controller_Button(pinZ)\n self.dead_zone = 0.01\n self.center_x = 0\n self.center_y = 0\n self.min_x = -1\n self.max_x = 1\n self.min_y = -1\n self.max_y = 1\n \n def calibrate(self, dead_zone, \n center_x=0.0, center_y=0.0, \n x_min=-1.0, x_max=1.0, \n y_min=-1.0, y_max=1.0):\n # \"\"\" calibrate the analog-stick to remove drift (nonzero values even in resting position) \n # and rescale to full [-1,1] range for the xy-inputs.\n \n # After calibration, the analog-stick \n # - does not react (returns 0) until it exceeds a value above the \"dead_zone\" range.\n # - returns values in the range [-1, 1] when pushed to the extremes and 0 at rest.\n \n # Parameters:\n # dead_zone (int): range of xy-values (negative too) that should be mapped to 0. \n # Default: 0.01 \n # center_x (int): returned value for get_x, when the stick is not moved (before calibration). \n # Default: 0.0\n # center_y (int): returned value for get_y, when the stick is not moved (before calibration). \n # Default: 0.0\n # x_min (int): minimal possible value for x (before calibration). Default: -1.0\n # x_max (int): maximal possible value for x (before calibration). Default: 1.0\n # y_min (int): minimal possible value for y (before calibration). Default: -1.0\n # y_max (int): maximal possible value for y (before calibration). Default: 1.0\n # \"\"\"\n self.dead_zone = min(0.2, max(0.01,dead_zone))\n self.center_x = min(0.4, max(-0.4,center_x))\n self.center_y = min(0.5, max(-0.5,center_y))\n self.min_x = min(-0.5, max(-1.0,x_min))\n self.max_x = min(1.0, max(0.5,x_max))\n self.min_y = min(-0.5, max(-1.0,y_min))\n self.max_y = min(1.0, max(0.5,y_max))\n\n def _remap(self, value, center, v_min, v_max):\n # \"\"\" internal function that applies remapping of the values according to the calibration.\n # The returned value will live in a possible space from [-1,1] with center at 0.\n \n # Parameters:\n # value (float): the input value to remap to the desired range.\n # center (float): the resting value before calibration.\n # v_min (float): the minimally attainable value before calibration.\n # v_max (float): the maximally attainable value before calibration.\n\n # Returns:\n # v (float): remapped parameter value according to calibration.\n # \"\"\"\n v = value - 1.0 - center\n if abs(v) - self.dead_zone/2.0 > 0.0:\n if v < 0.0:\n v = v / abs(v_min - center)\n else:\n v = v / abs(v_max - center)\n v = min(1.0, max(-1.0, v))\n v = 0.0 if abs(v) <= self.dead_zone else v\n return v\n\n def get_x(self):\n # \"\"\" get the current x-axis value of the analog stick.\n \n # Returns:\n # (float): position of x-axis in range [-1,1] (left to right). 0 is resting position. (after calibration)\n # \"\"\"\n v_raw = (self.pin_x.read_analog() / 512.0)\n v = self._remap(v_raw, self.center_x, self.min_x, self.max_x)\n return v\n\n def get_y(self):\n # \"\"\" get the current y-axis value of the analog stick.\n \n # Returns:\n # (float): position of y-axis in range [-1,1] (down to up). 0 is resting position. (after calibration)\n # \"\"\"\n v_raw = (self.pin_y.read_analog() / 512.0)\n v = self._remap(v_raw, self.center_y, self.min_y, self.max_y)\n return v\n\n def get_z(self):\n # \"\"\" get the current z-button state as an int. 1 = pressed, 0 = not pressed. \"\"\"\n return 1 if self.button_z.is_pressed() else 0\n\n def is_pressed(self):\n # \"\"\" returns if the z-button is currently pressed as a bool.\"\"\"\n return self.button_z.is_pressed()\n \n def was_pressed(self):\n # \"\"\" returns if the z-button was pressed (down) before the last call to this function.\"\"\"\n return self.button_z.was_pressed()\n \n def get_presses(self):\n # \"\"\" returns how often the z-button was pressed (down) before the last call to this function.\"\"\"\n return self.button_z.get_presses()\n\n# Controller LED and vibration motor\ndef vibrate(state):\n # \"\"\" Set the state of the controllers vibration motor. 0=Off, 1=On.\n # Also affects the controllers blue LED next to the motor. \"\"\"\n pin12.write_digital(state)\n\n# Left side of controller (black joystick)\njoystick = _Controller_Analog_Stick(pin1, pin2, pin8)\n# also make the joystick button accessible independently.\nbutton_z = joystick.button_z\n\n# Right side of controller (4 colored buttons)\nbutton_c = _Controller_Button(pin13)\nbutton_green = button_c\nbutton_d = _Controller_Button(pin14)\nbutton_yellow = button_d\nbutton_e = _Controller_Button(pin15)\nbutton_red = button_e\nbutton_f = _Controller_Button(pin16)\nbutton_blue = button_f\n\n# Back side of controller (2 white buttons, same as default buttons)\ntrigger_left = button_a\ntrigger_right = button_b\n\n\ndef _update_controller_buttons():\n # \"\"\" function to be called repeatedly that updates the state of all the controllers buttons. \n # It is necessary to run this function regularly to simulate the standard microbit button behaviour. \"\"\"\n global button_c\n global button_d\n global button_e\n global button_f\n global joystick\n\n button_c._update_state()\n button_d._update_state()\n button_e._update_state()\n button_f._update_state()\n joystick.button_z._update_state()\n\nrun_every(_update_controller_buttons, days=0, h=0, min=0, s=0, ms=33) # ~30 Updates per Second\n",
|
|
12
|
+
"mbxgo": "from microbit import *\n\n_speed = 50\n_XGOInit = False\n_TX = pin14\n_RX = pin13\n\n\ndef checkInit(func):\n def wrapper(*args, **kwargs):\n global _XGOInit\n if not _XGOInit:\n init_xgo_serial(_TX, _RX)\n return func(*args, **kwargs)\n return wrapper\n\n\ndef _map(speed, in_min, in_max, out_min, out_max):\n return (speed - in_min) * (out_max - out_min) // (in_max - in_min) + out_min\n\n\n@checkInit\ndef _move(direction, speed):\n move_buffer = bytearray(9)\n move_buffer[0] = 0x55\n move_buffer[1] = 0x00\n move_buffer[2] = 0x09\n move_buffer[3] = 0x00\n move_buffer[7] = 0x00\n move_buffer[8] = 0xAA\n\n speed = max(0, min(100, speed))\n\n if direction == 0:\n move_buffer[4] = 0x30\n move_buffer[5] = _map(speed, 0, 100, 128, 255)\n elif direction == 1:\n move_buffer[4] = 0x30\n move_buffer[5] = _map(speed, 0, 100, 128, 0)\n elif direction == 2:\n move_buffer[4] = 0x31\n move_buffer[5] = _map(speed, 0, 100, 128, 0)\n elif direction == 3:\n move_buffer[4] = 0x31\n move_buffer[5] = _map(speed, 0, 100, 128, 255)\n\n move_buffer[6] = ~(0x09 + 0x00 + move_buffer[4] + move_buffer[5]) & 0xFF\n\n uart.write(move_buffer)\n\n\n@checkInit\ndef clampX(milimeters=50):\n clampBuffer = bytearray(9)\n clampBuffer[0] = 0x55\n clampBuffer[1] = 0x00\n clampBuffer[2] = 0x09\n clampBuffer[3] = 0x00\n clampBuffer[4] = 0x73\n clampBuffer[7] = 0x00\n clampBuffer[8] = 0xAA\n\n clampBuffer[5] = milimeters\n clampBuffer[6] = ~(0x09 + 0x00 + 0x73 + clampBuffer[5]) & 0xFF\n\n uart.write(clampBuffer)\n sleep(1000)\n\n\n@checkInit\ndef clampZ(milimeters=50):\n clampBuffer = bytearray(9)\n clampBuffer[0] = 0x55\n clampBuffer[1] = 0x00\n clampBuffer[2] = 0x09\n clampBuffer[3] = 0x00\n clampBuffer[4] = 0x74\n clampBuffer[7] = 0x00\n clampBuffer[8] = 0xAA\n\n clampBuffer[5] = milimeters\n clampBuffer[6] = ~(0x09 + 0x00 + 0x74 + clampBuffer[5]) & 0xFF\n\n uart.write(clampBuffer)\n sleep(1000)\n\n\n@checkInit\ndef clamp(force):\n clampBuffer = bytearray(9)\n clampBuffer[0] = 0x55\n clampBuffer[1] = 0x00\n clampBuffer[2] = 0x09\n clampBuffer[3] = 0x00\n clampBuffer[4] = 0x71\n clampBuffer[7] = 0x00\n clampBuffer[8] = 0xAA\n\n clampBuffer[5] = force\n clampBuffer[6] = ~(0x09 + 0x00 + 0x71 + clampBuffer[5]) & 0xFF\n\n uart.write(clampBuffer)\n sleep(1000)\n\n\ndef init_xgo_serial(tx_pin, rx_pin, baudrate=115200):\n global _XGOInit\n uart.init(baudrate=baudrate, tx=tx_pin, rx=rx_pin)\n init_action()\n _XGOInit = True\n\n\ndef init_action():\n commands_buffer = bytearray(9)\n commands_buffer[0] = 0x55\n commands_buffer[1] = 0x00\n commands_buffer[2] = 0x09\n commands_buffer[3] = 0x00\n commands_buffer[4] = 0x3E\n commands_buffer[5] = 0xFF\n commands_buffer[6] = ~(0x09 + 0x00 + 0x3E + 0xFF) & 0xFF\n commands_buffer[7] = 0x00\n commands_buffer[8] = 0xAA\n\n uart.write(commands_buffer)\n sleep(2000)\n\n\n@checkInit\ndef action(id):\n commands_buffer = bytearray(9)\n commands_buffer[0] = 0x55\n commands_buffer[1] = 0x00\n commands_buffer[2] = 0x09\n commands_buffer[3] = 0x00\n commands_buffer[4] = 0x3E\n commands_buffer[5] = id\n commands_buffer[6] = ~(0x09 + 0x00 + 0x3E + id) & 0xFF\n commands_buffer[7] = 0x00\n commands_buffer[8] = 0xAA\n\n uart.write(commands_buffer)\n sleep(2000)\n\n\ndef changeInit(tx, rx):\n global _TX\n global _RX\n _TX = tx\n _RX = rx\n init_xgo_serial(_TX, _RX)\n\n\n@checkInit\ndef setSpeed(speed):\n global _speed\n _speed = speed\n\n\ndef forward():\n _move(0, _speed)\n\n\ndef backward():\n _move(1, _speed)\n\n\ndef left():\n _move(2, _speed)\n\n\ndef right():\n _move(3, _speed)\n",
|
|
13
|
+
"mbglow": "# mbglow.py\n# V1.5, June 30, 2018\n# Module for a crash course in Python\n# An implementation of a glowbug, firefly (Leuchtkaefer)\n\nfrom microbit import *\n\n_x = 0\n_y = 0\n_dir = 0\n_speed = 50\n_trace = True\n_visible = False\n\ndef makeGlow():\n global _visible\n display.set_pixel(2, 2, 9)\n _visible = True\n\ndef clear():\n display.clear()\n \ndef forward(): \n _forward(1)\n\ndef back(): \n _forward(-1)\n \ndef right(angle):\n global _dir\n _dir = (_dir + angle) % 360\n\ndef left(angle):\n right(-angle)\n\ndef setPos(x, y):\n global _x, _y\n _x = x\n _y = y\n _render()\n\ndef getPos():\n return _x, _y\n\ndef setSpeed(speed):\n global _speed\n _speed = speed\n \ndef showTrace(enable):\n global _trace\n _trace = enable \n\ndef isLit():\n return (display.get_pixel(_x + 2, 4 - (_y + 2)) == 9)\n \ndef _forward(s):\n global _x, _y\n sleep(2000 - _speed * 20)\n d = _dir // 45\n if d in [1, 2, 3]: \n _x += s\n if d in [5, 6, 7]: \n _x -= s\n if d in [0, 1, 7]: \n _y += s\n if d in [3, 4, 5]: \n _y -= s\n _render()\n\ndef _render():\n if not _visible:\n print(\"Use \\\"makeGlow()\\\" to create a Glow.\")\n raise Exception(\"Glow not initialized.\")\n if not _trace:\n display.clear()\n if -2 <= _x <= 2 and -2 <= _y <= 2: \n display.set_pixel(_x + 2, 4 - (_y + 2), 9)",
|
|
14
|
+
"mbthetabot": "from microbit import *\nfrom utime import ticks_us, sleep_us\nfrom neopixel import *\n\n_speedPercent = 50\n_powerByteL = 40\n_powerByteR = 40\n_powerBytesLUT = bytes(b'\\x00\\x0b\\x0b\\x0c\\x0c\\x0d\\x0d\\x0d\\x0e\\x0e\\x0f\\x0f\\x0f\\x10\\x10\\x11\\x11\\x11\\x12\\x12\\x13\\x13\\x13\\x14\\x14\\x15\\x15\\x15\\x16\\x16\\x17\\x17\\x17\\x18\\x19\\x1a\\x1b\\x1b\\x1c\\x1d\\x1e\\x1f\\x20\\x21\\x22\\x23\\x23\\x24\\x25\\x26\\x27\\x28\\x29\\x2a\\x2b\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x36\\x38\\x3a\\x3c\\x3f\\x41\\x44\\x46\\x49\\x4c\\x4f\\x53\\x56\\x5a\\x5e\\x62\\x67\\x6b\\x70\\x75\\x7b\\x81\\x87\\x8d\\x94\\x9b\\xa3\\xab\\xb4\\xbd\\xc6\\xd0\\xdb\\xe6\\xf2\\xff')\n\n_powerOffset = 0\n_powerDifferential = 0\n_arcScaling = 0\n\n_ADDR_ATM = 0x22\n_nbLeds = 14\n\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n pinsL = (pin14, pin13)\n pinsR = (pin16, pin15)\n\n pinsL[dirL].write_analog(powerL)\n pinsL[1 - dirL].write_analog(0)\n\n pinsR[dirR].write_analog(powerR)\n pinsR[1 - dirR].write_analog(0)\n\n\ndef _setSingleMotor(side, direction, power):\n if side == 0:\n pins = (pin14, pin13)\n elif side == 2:\n pins = (pin16, pin15)\n\n pins[direction].write_analog(power)\n pins[1 - direction].write_analog(0)\n\n\ndef _getArcBytes(r):\n outerSpeed = _speedPercent\n rCm = int(r * 100)\n threshold = outerSpeed - max(rCm + 20, 40)\n if threshold <= 0:\n outerSpeed = min(max(rCm + 40, 40), 100)\n reducedSpeed = 0\n if rCm >= 4:\n flattening = (100 - outerSpeed) // 2\n reducedSpeed = (rCm * 10 - 35) / \\\n (rCm * (11 + (_arcScaling-4)/10) + 90 + flattening)\n reducedSpeed = reducedSpeed * outerSpeed\n innerByte = _getPowerByteLUT(int(reducedSpeed), 0)\n outerByte = _getPowerByteLUT(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\n\ndef calibrate(offset, differential=0, arcScaling=0):\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n\n _powerOffset = max(min(int(offset), 150), -10)\n _powerDifferential = max(min(int(differential), 150), -150)\n _arcScaling = max(min(arcScaling, 50), -15)\n setSpeed(_speedPercent)\n\n\ndef setSpeed(speed):\n global _speedPercent\n global _powerByteL\n global _powerByteR\n\n _speedPercent = int(min(max(speed, 0), 100))\n powerByte = _getPowerByteLUT(_speedPercent, _powerOffset)\n boost = round((1 - _speedPercent / 100) *\n abs(_powerDifferential)) if _speedPercent > 0 else 0\n reduction = round((_speedPercent / 100) * abs(_powerDifferential))\n if _powerDifferential > 0:\n _powerByteL = powerByte - reduction\n _powerByteR = powerByte + boost\n else:\n _powerByteL = powerByte + boost\n _powerByteR = powerByte - reduction\n\n\ndef _getPowerByteLUT(speed, offset):\n speedIndex = int(speed * (len(_powerBytesLUT) - 1) / 100)\n return min(_powerBytesLUT[speedIndex] + offset, 1023)\n\n\ndef stop():\n _setMotors(0, 0, 0, 0)\n\n\ndef forward():\n _setMotors(0, _powerByteL, 0, _powerByteR)\n\n\ndef backward():\n _setMotors(1, _powerByteL, 1, _powerByteR)\n\n\ndef left():\n _setMotors(1, _powerByteL, 0, _powerByteR)\n\n\ndef right():\n _setMotors(0, _powerByteL, 1, _powerByteR)\n\n\ndef rightArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, outer, 0, inner)\n\n\ndef leftArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, inner, 0, outer)\n\n\ndef getDistance():\n pin12.write_digital(1)\n sleep_us(10)\n pin12.write_digital(0)\n pin12.set_pull(pin15.NO_PULL)\n while pin12.read_digital() == 0:\n pass\n start = ticks_us()\n while pin12.read_digital() == 1:\n pass\n end = ticks_us()\n echo = end-start\n distance = int(0.01715 * echo)\n return distance\n\n\ndef setLED(position, red, green, blue):\n global _ADDR_ATM\n i2c_data = bytearray(5)\n\n i2c_data[0] = 1\n\n i2c_data[1] = position\n\n i2c_data[2] = red\n i2c_data[3] = green\n i2c_data[4] = blue\n\n i2c.write(_ADDR_ATM, i2c_data)\n\n\ndef fill(red, green, blue):\n for position in range(_nbLeds):\n setLED(position, red, green, blue)\n\n\ndef readLine(side): # 0=left 1=right\n i2c.write(_ADDR_ATM, bytearray([side + 1]), False)\n result = i2c.read(_ADDR_ATM, 2)\n result = result[0] + (result[1] << 8)\n return result\n\n\ndef readLight(side): # 0=left 1=right\n i2c.write(_ADDR_ATM, bytearray([side + 3]), False)\n result = i2c.read(_ADDR_ATM, 2)\n result = result[0] + (result[1] << 8)\n return result\n",
|
|
15
|
+
"mbrobot_legacy": "import gc\nfrom microbit import i2c, pin1, pin2, pin8, pin12, pin13, pin14, sleep\nimport machine\n\n_axe = 0.097\ndef w(d1, d2, s1, s2):\n try:\n i2c.write(0x10, bytearray([0, d1, s1]))\n i2c.write(0x10, bytearray([2, d2, s2]))\n except:\n print(\"Please switch on mbRobot!\")\n while True:\n pass\n \ndef setSpeed(speed):\n global _v\n if speed < 20:\n _v = speed + 5\n else:\n _v = speed \n\ndef forward():\n w(0, 0, _v, _v)\n\ndef backward():\n w(1, 1, _v, _v)\n \ndef stop():\n w(0, 0, 0, 0)\n \ndef right():\n w(0 if _v > 0 else 1, 1 if _v > 0 else 0, int(_v * 0.9), int(_v * 0.9)) \n\ndef left():\n w(1 if _v > 0 else 0, 0 if _v > 0 else 1, int(_v * 0.9) , int(_v * 0.9))\n\ndef rightArc(r):\n v = abs(_v)\n if r < _axe:\n v1 = 0\n else: \n f = (r - _axe) / (r + _axe) * (1 - v * v / 200000) \n v1 = int(f * v)\n if _v > 0:\n w(0, 0, v, v1)\n else:\n w(1, 1, v1, v)\n\ndef leftArc(r):\n v = abs(_v)\n if r < _axe:\n v1 = 0\n else:\n f = (r - _axe) / (r + _axe) * (1 - v * v / 200000) \n v1 = int(f * v)\n if _v > 0:\n w(0, 0, v1, v)\n else:\n w(1, 1, v, v1)\n\nexit = stop\ndelay = sleep\n\ndef getDistance():\n pin1.write_digital(1)\n pin1.write_digital(0)\n p = machine.time_pulse_us(pin2, 1, 50000)\n cm = int(p / 58.2 + 0.5)\n return cm if cm > 0 else 255\n\ndef setLED(on):\n pin8.write_digital(on)\n pin12.write_digital(on)\n \ndef setServo(S, Angle):\n if S == \"S1\":\n Servo = 0x14\n if S == \"S2\":\n Servo = 0x15\n buf = Servo, Angle\n i2c.write(0x10, bytes(buf)) \n\npin2.set_pull(pin2.NO_PULL)\n_v = 50 # entspricht default 50\nirLeft = pin13\nirRight = pin14\nledLeft = pin8\nledRight = pin12\n\nforward()",
|
|
16
|
+
"mbalarm": "# mbalarm.py\n\nimport music\n\n_m = ['c6:1', 'r', 'c6,1', 'r', 'r', 'r']\n\ndef setAlarm(on):\n if on:\n music.play(_m, wait = False, loop = True) \n else:\n music.stop()\n \n \ndef beep():\n music.pitch(2000, 200, wait = False)",
|
|
17
|
+
"mbminibit": "from microbit import *\nfrom neopixel import *\nimport utime\n\n_nbLeds = 4\n_np = NeoPixel(pin13, _nbLeds)\n\n_speedPercent = 50\n_powerLeft = 90\n_powerRight = 90\n\n_powerOffset = 0\n_powerDifferential = 0\n_arcScaling = 0\n\n_MAX_CM_DISTANCE = 500\n_CM_PER_MICROSECOND = 29.1\n\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n pin8.write_analog(powerL if dirL == 1 else 0)\n pin12.write_analog(0 if dirL == 1 else powerL)\n pin16.write_analog(0 if dirR == 1 else powerR)\n pin14.write_analog(powerR if dirR == 1 else 0)\n\n\ndef _pulse_in(pin, value, timeout):\n start_time = utime.ticks_us()\n while pin.read_digital() != value:\n if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:\n return 0\n start_time = utime.ticks_us()\n while pin.read_digital() == value:\n if utime.ticks_diff(utime.ticks_us(), start_time) > timeout:\n return 0\n return utime.ticks_diff(utime.ticks_us(), start_time)\n\n\ndef _getArcBytes(r):\n outerSpeed = _speedPercent\n if r > 0:\n innerSpeed = outerSpeed * max(0.2, min(1, 1 - r / 100))\n else:\n innerSpeed = 0\n\n innerByte = _convertSpeedToAnalogValue(int(innerSpeed), 0)\n outerByte = _convertSpeedToAnalogValue(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\n\ndef _convertSpeedToAnalogValue(speed, offset):\n analogValue = int(speed * 255 / 100) + offset\n return min(max(analogValue, 0), 255)\n\n\ndef calibrate(offset, differential=0, arcScaling=0):\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n _powerOffset = max(min(int(offset), 100), -10)\n _powerDifferential = max(min(int(differential), 150), -150)\n _arcScaling = max(min(arcScaling, 50), -15)\n setSpeed(_speedPercent)\n\n\ndef setSpeed(speed):\n global _speedPercent\n global _powerLeft\n global _powerRight\n _speedPercent = int(min(max(speed, 0), 100))\n powerByte = _convertSpeedToAnalogValue(_speedPercent, _powerOffset)\n boost = round((1 - _speedPercent / 100) *\n abs(_powerDifferential)) if _speedPercent > 0 else 0\n reduction = round((_speedPercent / 100) * abs(_powerDifferential))\n if _powerDifferential > 0:\n _powerLeft = powerByte - reduction\n _powerRight = powerByte + boost\n else:\n _powerLeft = powerByte + boost\n _powerRight = powerByte - reduction\n\n\ndef stop():\n _setMotors(0, 0, 0, 0)\n\n\ndef forward():\n _setMotors(0, _powerLeft, 0, _powerRight)\n\n\ndef backward():\n _setMotors(1, _powerLeft, 1, _powerRight)\n\n\ndef left():\n _setMotors(1, _powerLeft, 0, _powerRight)\n\n\ndef right():\n _setMotors(0, _powerLeft, 1, _powerRight)\n\n\ndef rightArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, outer, 0, inner)\n\n\ndef leftArc(radius):\n inner, outer = _getArcBytes(radius)\n _setMotors(0, inner, 0, outer)\n\n\ndef setLED(pos, red, green, blue):\n _np[pos] = (red, green, blue)\n _np.show()\n\n\ndef fill(red, green, blue):\n for i in range(_nbLeds):\n _np[i] = (red, green, blue)\n _np.show()\n\n\ndef getDistance():\n trig = pin15\n echo = pin15\n d = 10\n trig.set_pull(trig.NO_PULL)\n for _ in range(10):\n trig.write_digital(0)\n utime.sleep_us(2)\n trig.write_digital(1)\n utime.sleep_us(10)\n trig.write_digital(0)\n duration = _pulse_in(echo, 1, _MAX_CM_DISTANCE * _CM_PER_MICROSECOND)\n if duration > 0:\n d = duration\n break\n return round(d / _CM_PER_MICROSECOND)\n",
|
|
18
|
+
"mbrobot_plusV2": "# mbrobot_plusV2.py\n# Date 10/09/24\n\nfrom microbit import i2c, pin0, pin1, pin2, pin13, pin14, pin15, sleep\nimport gc\nimport machine\nimport music\nimport neopixel\n\n# Motor state\n_speedPercent = 50\n_powerByteL = 50\n_powerByteR = 50\n_motorState = bytearray(5)\n_powerBytesLUT = bytes(b'\\x00\\x0f\\x10\\x10\\x11\\x12\\x12\\x13\\x13\\x14\\x15\\x15\\x16\\x16\\x17\\x18\\x18\\x19\\x19\\x1a\\x1b\\x1b\\x1c\\x1c\\x1d\\x1e\\x1e\\x1f\\x1f\\x20\\x21\\x21\\x22\\x22\\x23\\x24\\x24\\x25\\x25\\x26\\x27\\x29\\x2a\\x2b\\x2c\\x2d\\x2e\\x2f\\x30\\x31\\x32\\x33\\x34\\x35\\x36\\x37\\x38\\x39\\x3a\\x3b\\x3b\\x3c\\x3e\\x3f\\x41\\x43\\x45\\x47\\x49\\x4b\\x4d\\x50\\x52\\x55\\x58\\x5b\\x5e\\x61\\x65\\x69\\x6d\\x71\\x75\\x7a\\x7f\\x84\\x89\\x8f\\x95\\x9b\\xa2\\xa9\\xb1\\xb9\\xc1\\xca\\xd3\\xdd\\xe8\\xf3\\xff')\n\n# Calibration data\n_powerOffset = 0\n_powerDifferential = 0\n_arcScaling = 0\n_servoMinPulse = 25\n_servoMaxPulse = 131\n\n# Signaling objects and buffers\n_ledState = bytearray(b'\\x0B\\0\\0')\n_underglowNP = neopixel.NeoPixel(pin15, 4)\nnp_rgb_pixels = _underglowNP\n_alarmSequence = ['c5:1', 'r', 'c5,1', 'r:3']\n\n_UNCONNECTEDERRORMSG = \"Please connect to Maqueen robot and switch it on.\"\n\n# Utility functions\n\n\ndef _setMotors(dirL, powerL, dirR, powerR):\n # \"\"\"Write Motor State via i2c\n\n # Parameters:\n # dirL (0/1): Direction of left Wheel. 0=forward, 1=backward\n # powerL (int): Power of left Wheel in range [0,255].\n # dirR (0/1): Direction of right Wheel. 0=forward, 1=backward\n # powerR (int): Power of right Wheel in range [0,255].\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n global _motorState\n _motorState[1] = dirL\n _motorState[2] = powerL\n _motorState[3] = dirR\n _motorState[4] = powerR\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\n\ndef _setSingleMotor(side, dir, power):\n # \"\"\"Write Motor State of a single Motor via i2c\n\n # Parameters:\n # side (0/2): Selection of the Wheel. 0=left, 2=right\n # dir (0/1): Direction for that Wheel. 0=forward, 1=backward\n # power (int): Power for that Wheel in range [0,255].\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n global _motorState\n _motorState[1 + side] = dir\n _motorState[2 + side] = power\n try:\n i2c.write(0x10, _motorState)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n\n# _getPowerByte was used to create LookUpTable (_powerBytesLUT) used in _getPowerByteLUT to reduce Memory Leaks.\n# def _getPowerByte(speed, offset):\n# # \"\"\"Computes the power value for a given speed in %.\n# # It accouts for the nonlinearity of motor strength.\n# # This is the original function that generates the LUT.\n#\n# # Parameter:\n# # speed (number): Desired speed of the Robot in %. Range [0,100].\n# # offset (int): basic power offset to add to the function.\n# # Returns:\n# # int: Power in range [0,255] to write to the motors via i2c.\n# # \"\"\"\n# if speed <= 0:\n# return 0\n# elif speed < 40:\n# return int(0.6 * speed + 15 + offset)\n# elif speed < 60:\n# return int(speed + offset)\n# elif speed < 100:\n# return int(min(1.05546 ** speed + 34 + offset, 255))\n# else:\n# return 255\n\n\ndef _getPowerByteLUT(speed, offset):\n # \"\"\"Lookup Table version of _getPowerByte\"\"\"\n return min(_powerBytesLUT[speed] + offset, 255)\n\n\ndef _getArcBytes(r):\n # \"\"\"Computes the power bytes to drive an arc.\n\n # Parameter:\n # r (float): Radius in meters of the desired Arc.\n # Measured from the center of the axle.\n # Returns:\n # (int, int): Power byte values for each motor.\n # First the outer Wheels byte [0,255],\n # then the inner Wheels byte [0,255].\n # \"\"\"\n rmm = int(r * 100) # radius in mm\n outerSpeed = _speedPercent\n # adjust outer speed for unhealthy values\n if outerSpeed < 25:\n outerSpeed = 25\n speedFix = min(abs(outerSpeed - 70), 20) / 20\n reducedSpeed = 0\n if rmm > 5:\n # formula derived from data and simplified\n n = outerSpeed * (3 * _arcScaling - outerSpeed - 9 * rmm + 220)\n d = -14 * _arcScaling + outerSpeed - 200 + 3 * outerSpeed - 10 * rmm - 290\n reducedSpeed = int(n/d)\n if reducedSpeed < 2: # fix values at low radii (negative values too)\n reducedSpeed = 2 if rmm > 15 else 1\n innerByte = _getPowerByteLUT(int(reducedSpeed), 0)\n outerByte = _getPowerByteLUT(int(outerSpeed), 0)\n return (innerByte, outerByte)\n\n# Movement functions\n\n\ndef calibrate(offset, differential=0, arcScaling=0):\n # \"\"\"Adjust the driving behaviour of the robots\n\n # Parameters:\n # offset (int): Offsets the minimal power of the motors.\n # Range [-10,50]. Highly affected by battery level.\n # Adjust this value until it starts moving at speed 1%.\n # differential (int, optional): Adjusts power difference\n # of left and right Wheel. Range [-150, 150].\n # Varies unpredictably with different speeds.\n # If a Robot steers left when driving forward: negative value\n # If a Robot steers right when driving forward: positive value\n # Perfectly straight driving Robots can leave this at 0.\n # arcScaling (int, optional): Adjusts the radius\n # driven by leftArc/rightArc. Valid range [-50, 50].\n # If the Robots radius is too large: positive value\n # If the Robots radius is too small: negative value\n # This then adjusts all radii for this Robot, by\n # scaling it's internal function to the new range.\n # \"\"\"\n global _powerDifferential\n global _powerOffset\n global _arcScaling\n _powerOffset = max(min(int(offset), 50), -14)\n _powerDifferential = max(min(int(differential), 150), -150)\n _arcScaling = max(min(arcScaling, 50), -50)\n setSpeed(_speedPercent)\n\n\ndef setSpeed(speed):\n # \"\"\"sets the speed for future motion\n\n # Parameter:\n # speed (int): in Range [0,100] as % of desired velocity.\n # \"\"\"\n global _speedPercent\n global _powerByteL\n global _powerByteR\n _speedPercent = int(min(max(speed, 0), 100))\n powerByte = _getPowerByteLUT(_speedPercent, _powerOffset)\n boost = round((1 - _speedPercent / 100) *\n abs(_powerDifferential)) if _speedPercent > 0 else 0\n reduction = round((_speedPercent / 100) * abs(_powerDifferential))\n if _powerDifferential > 0:\n _powerByteL = powerByte - reduction\n _powerByteR = powerByte + boost\n else:\n _powerByteL = powerByte + boost\n _powerByteR = powerByte - reduction\n\n\ndef resetSpeed():\n setSpeed(50)\n\n\ndef stop():\n _setMotors(0, 0, 0, 0)\n\n\ndef forward():\n _setMotors(0, _powerByteL, 0, _powerByteR)\n\n\ndef backward():\n _setMotors(1, _powerByteL, 1, _powerByteR)\n\n\ndef left():\n _setMotors(1, _powerByteL, 0, _powerByteR)\n\n\ndef right():\n _setMotors(0, _powerByteL, 1, _powerByteR)\n\n\ndef rightArc(radius):\n # \"\"\"radius must be given in meters.\"\"\"\n inner, outer = _getArcBytes(radius)\n _setMotors(0, outer, 0, inner)\n\n\ndef leftArc(radius):\n # \"\"\"radius must be given in meters.\"\"\"\n inner, outer = _getArcBytes(radius)\n _setMotors(0, inner, 0, outer)\n\n\nclass Motor:\n def __init__(self, side):\n # \"\"\"Create a single motor.\n\n # Parameter:\n # side (0/2): 0=left, 2=right\n # \"\"\"\n self._side = side\n\n def rotate(self, speed):\n # \"\"\"Controls rotation of this motor.\n\n # Parameters:\n # speed (int): Desired speed in %.\n # Valid range [-100,100].\n # Negative values are for backward turning.\n # \"\"\"\n speedClamped = int(min(max(abs(speed), 0), 100))\n power = _getPowerByteLUT(speedClamped, _powerOffset)\n direction = 0 if speed > 0 else 1\n _setSingleMotor(self._side, direction, power)\n\n\ndef setServo(servo, angle):\n # \"\"\"Moves the Servo to position angle.\n # Servos must be connected to the Maqueen Plus V2's \"P\" connectors.\n # They are located at the back of the robot.\n\n # Parameters:\n # servo (str): Desired Servo Port. Either 'P0', 'P1' or 'P2'.\n # angle (int): Desired angle in degrees. Range [0,180].\n\n # raises:\n # ValueError: if arguments are out of valid range\n # \"\"\"\n if servo == \"P0\" or servo == 'S1':\n pin = pin0\n elif servo == \"P1\" or servo == 'S2':\n pin = pin1\n elif servo == \"P2\":\n pin = pin2\n else:\n raise ValueError(\"Unknown Servo. Please use 'P0', 'P1' or 'P2'.\")\n\n if angle < 0 or angle > 180:\n raise ValueError(\"Invalid angle. Must be between 0 and 180\")\n\n frac = (_servoMaxPulse - _servoMinPulse) * int(angle)\n offset = (frac >> 8) + (frac >> 10) + (frac >> 11) + (frac >> 12) # / 180\n usPulseTime = _servoMinPulse + offset # min + (max-min) * (angle / 180)\n pin.set_analog_period(20)\n pin.write_analog(usPulseTime)\n\n\ndef setMinAngleVal(duty):\n # \"\"\" Sets the minimal pulse duty cycle for the servo.\n # It should match 1ms of a 20ms period, where the duty is in range [0,1024].\n # Theoretically: 1/20*1024 = 51. Practically: Default is 25. adjust carefully in steps of 1.\n #\n # Parameter:\n # duty (int): The minimal duty amount for a write_analog signal with 20ms pulse.\n # It should approximate 1ms. 1ms/20ms*1024 = min duty = 0-degree position for the servo.\n # \"\"\"\n global _servoMinPulse\n _servoMinPulse = int(duty)\n\n\ndef setMaxAngleVal(duty):\n # \"\"\" Sets the maximal pulse duty cycle for the servo.\n # It should match 2ms of a 20ms period, where the duty is in range [0,1024].\n # Theoretically: 2/20*1024 = 102. Practically: Default is 131. adjust carefully to increase range of the servo.\n #\n # Parameter:\n # duty (int): The maximal duty amount for a write_analog signal with 20ms pulse.\n # It should approximate 2ms. 2ms/20ms*1024 = max duty = 180-degree position for the servo.\n # \"\"\"\n global _servoMaxPulse\n _servoMaxPulse = int(duty)\n\n# Sensor functions\n\n\nclass IRSensor:\n _address = bytes(b'\\x1D')\n\n def __init__(self, index):\n # \"\"\"Create a new IR sensor.\n\n # Parameter:\n # index (int): 0=R2, 1=R1, 2=M, 3=L1, 4=L2\n # \"\"\"\n self._index = index\n\n def read_digital(self):\n # \"\"\"Returns if the surface below is dark or bright.\n # Result can be adjusted by putting the sensor on the dark\n # surface and pressing the LineKey calibration button on the\n # Robot for a few seconds, until the LED's blink.\n\n # Returns:\n # 0 if the surface is dark. No light was reflected (in Air).\n # 1 if the surface is bright. A lot of light was reflected.\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n try:\n i2c.write(0x10, IRSensor._address)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n byte = ~i2c.read(0x10, 1)[0]\n # mask out corresponding bit, from returned byte.\n return (byte & (2 ** self._index)) >> self._index\n\n def read_analog(self):\n # \"\"\"Returns the brightness of the surface as a byte.\n\n # Returns:\n # int: amount of reflection of light in range [0,255].\n #\n # raises:\n # RuntimeError: if Robot is switched off or unconnected. (replaces ENODEV error)\n # \"\"\"\n try:\n i2c.write(0x10, IRSensor._address)\n except:\n raise RuntimeError(_UNCONNECTEDERRORMSG)\n # Buffer structure:\n # 1 Byte Bitmask (for digital redout),\n # then 10 Bytes analog byte values (every second entry is a value).\n buffer = i2c.read(0x10, 11)\n return buffer[1 + self._index * 2]\n\n\ndef ir_read_values_as_byte():\n # \"\"\"get single byte with bit encoding of each Infrared sensor state\n # Bits: 0=R2, 1=R1, 2=M, 3=L1, 4=L2\n # \"\"\"\n i2c.write(0x10, bytearray([0x1D]))\n buf = i2c.read(0x10, 1)\n return ~buf[0]\n\n\ndef getDistance():\n # \"\"\"uses the ultrasonic sensor to measure distance\n\n # Returns:\n # int: valid Distance as cm in range [0,500].\n # For measurement errors or larger distances: 255.\n # \"\"\"\n pin13.write_digital(1)\n pin13.write_digital(0)\n p = machine.time_pulse_us(pin14, 1, 50000)\n # approximate division: p / 58.2 - 0.5\n cm = (p >> 6) + (p >> 10) + (p >> 11) + (p >> 12) + 1\n return max(min(cm, 500), 0) if cm > 0 else 255\n\n# Signaling functions\n\n\ndef setLED(state, stateR=None):\n # \"\"\"Set the front red LED's.\n\n # Parameters:\n # state (0/1): Sets the state of the left LED.\n # if stateR is omitted, then both LEDS.\n # 0=Off, 1=On\n # stateR (0/1/None, optional): Sets the right LED state.\n # 0=Off, 1=On, Default=None uses \"state\" for right LED.\n # \"\"\"\n global _ledState\n stateR = stateR if stateR != None else state\n _ledState[1] = state\n _ledState[2] = stateR\n i2c.write(0x10, _ledState)\n\n\ndef setLEDLeft(state):\n # \"\"\"state: 0=Off, 1=On\"\"\"\n global _ledState\n _ledState[1] = state\n i2c.write(0x10, _ledState)\n\n\ndef setLEDRight(state):\n # \"\"\"state: 0=Off, 1=On\"\"\"\n global _ledState\n _ledState[2] = state\n i2c.write(0x10, _ledState)\n\n\ndef fillRGB(red, green, blue):\n # \"\"\"Uses Neopixel to set all 4 bottom RGB LEDs color.\n # Parameters (red,green,blue) are each a byte in Range [0,255].\n # \"\"\"\n for i in range(4):\n _underglowNP[i] = (red, green, blue)\n _underglowNP.show()\nsetRGB=fillRGB\n\n\ndef clearRGB():\n _underglowNP.clear()\n\ndef posRGB(position, red, green, blue):\n # \"\"\"Uses Neopixel to set a single RGB LED of the robot.\n\n # Parameters:\n # position (int): position of the targeted LED.\n # Numbers are visible at underside of Robot.\n # 0=front left\n # 1=back left\n # 2=back right\n # 3=front right\n # red, green, blue (int): color byte value.\n # each in range [0,255].\n\n # raises:\n # ValueError: if position argument is out of valid range\n # \"\"\"\n if position < 0 or position > 3:\n raise ValueError(\"invalid RGB-LED position. Must be 0,1,2 or 3.\")\n _underglowNP[position] = (red, green, blue)\n _underglowNP.show()\n\n\ndef setAlarm(state):\n if state:\n music.play(_alarmSequence, wait=False, loop=True)\n else:\n music.stop()\n\n\ndef beep():\n music.pitch(440, 200, wait=False)\n\n# Class constants (for compatibilty)\n\n\nclass LEDState:\n ON = 1\n OFF = 0\n RED = 1\n\n\nclass IR:\n R2 = 0\n R1 = 1\n M = 2\n L1 = 3\n L2 = 4\n masks = [0x01, 0x02, 0x04, 0x08, 0x10]\n\n\n# Default instances\npin2.set_pull(pin2.NO_PULL)\ndelay = sleep\nirR2 = IRSensor(0)\nirR1 = IRSensor(1)\nirRight = irR1\nirM = IRSensor(2)\nirL1 = IRSensor(3)\nirLeft = irL1\nirL2 = IRSensor(4)\nmotL = Motor(0)\nmotR = Motor(2)\n"
|
|
19
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
from microbit import *
|
|
2
|
+
from neopixel import *
|
|
3
|
+
from utime import ticks_us, sleep_us
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
_v = 200
|
|
7
|
+
_nbLeds = 12
|
|
8
|
+
_np = NeoPixel(pin13, _nbLeds)
|
|
9
|
+
|
|
10
|
+
_powerDifferential = 0
|
|
11
|
+
_powerOffset = 0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def w(leftforward, leftbackward, rightforward, rightbackward):
|
|
15
|
+
if leftforward > 0 or rightforward > 0:
|
|
16
|
+
pin16.write_analog(leftforward + _powerDifferential)
|
|
17
|
+
pin8.write_analog(leftbackward)
|
|
18
|
+
pin14.write_analog(rightforward - _powerDifferential)
|
|
19
|
+
pin12.write_analog(rightbackward)
|
|
20
|
+
elif leftbackward > 0 or rightbackward > 0:
|
|
21
|
+
pin16.write_analog(leftforward)
|
|
22
|
+
pin8.write_analog(leftbackward + _powerDifferential)
|
|
23
|
+
pin14.write_analog(rightforward)
|
|
24
|
+
pin12.write_analog(rightbackward - _powerDifferential)
|
|
25
|
+
elif leftforward == 0 and rightforward == 0 and leftbackward == 0 and rightbackward == 0:
|
|
26
|
+
pin16.write_analog(0)
|
|
27
|
+
pin8.write_analog(0)
|
|
28
|
+
pin14.write_analog(0)
|
|
29
|
+
pin12.write_analog(0)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def forward():
|
|
33
|
+
w(_v, 0, _v, 0)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def backward():
|
|
37
|
+
w(0, _v, 0, _v)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def stop():
|
|
41
|
+
w(0, 0, 0, 0)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def right():
|
|
45
|
+
w(0, _v, _v, 0)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def left():
|
|
49
|
+
w(_v, 0, 0, _v)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def set_led(pos, red, green, blue):
|
|
53
|
+
_np[pos] = (red, green, blue)
|
|
54
|
+
_np.show()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def fill(red, green, blue):
|
|
58
|
+
for i in range(_nbLeds):
|
|
59
|
+
_np[i] = (red, green, blue)
|
|
60
|
+
_np.show()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def getDistance():
|
|
64
|
+
pin15.write_digital(1)
|
|
65
|
+
sleep_us(10)
|
|
66
|
+
pin15.write_digital(0)
|
|
67
|
+
pin15.set_pull(pin15.NO_PULL)
|
|
68
|
+
while pin15.read_digital() == 0:
|
|
69
|
+
pass
|
|
70
|
+
start = ticks_us()
|
|
71
|
+
while pin15.read_digital() == 1:
|
|
72
|
+
pass
|
|
73
|
+
end = ticks_us()
|
|
74
|
+
echo = end-start
|
|
75
|
+
distance = int(0.01715 * echo)
|
|
76
|
+
return distance
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def calibrate(offset, differential=0):
|
|
80
|
+
global _powerDifferential
|
|
81
|
+
global _powerOffset
|
|
82
|
+
global _arcScaling
|
|
83
|
+
|
|
84
|
+
_powerOffset = max(min(int(offset), 50), -50)
|
|
85
|
+
_powerDifferential = max(min(int(differential), 50), -50)
|
|
86
|
+
_arcScaling = max(min(arcScaling, 50), -50)
|
|
87
|
+
setSpeed(_v / 1023 * 100)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def setSpeed(percent):
|
|
91
|
+
global _v
|
|
92
|
+
speed = percent / 100 * 1023
|
|
93
|
+
speed += _powerOffset/100 * 1023
|
|
94
|
+
speed = min(max(speed, 0), 1023)
|
|
95
|
+
_v = speed
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def getLine(bit):
|
|
99
|
+
mask = 1 << bit
|
|
100
|
+
value = 0
|
|
101
|
+
try:
|
|
102
|
+
value = i2c.read(0x1c, 1)[0]
|
|
103
|
+
except OSError:
|
|
104
|
+
pass
|
|
105
|
+
if (value & mask) > 0:
|
|
106
|
+
return 1
|
|
107
|
+
else:
|
|
108
|
+
return 0
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def getLight(index):
|
|
112
|
+
if index == 0:
|
|
113
|
+
return pin1.read_analog()
|
|
114
|
+
elif index == 1:
|
|
115
|
+
return pin2.read_analog()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def leftArc(radius):
|
|
119
|
+
speed = _v
|
|
120
|
+
inner_wheel_speed = speed * (radius / (radius + 1))
|
|
121
|
+
w(inner_wheel_speed, 0, speed, 0)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def rightArc(radius):
|
|
125
|
+
speed = _v
|
|
126
|
+
inner_wheel_speed = speed * (radius / (radius + 1))
|
|
127
|
+
w(speed, 0, inner_wheel_speed, 0)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# mbglow.py
|
|
2
|
+
# V1.5, June 30, 2018
|
|
3
|
+
# Module for a crash course in Python
|
|
4
|
+
# An implementation of a glowbug, firefly (Leuchtkaefer)
|
|
5
|
+
|
|
6
|
+
from microbit import *
|
|
7
|
+
|
|
8
|
+
_x = 0
|
|
9
|
+
_y = 0
|
|
10
|
+
_dir = 0
|
|
11
|
+
_speed = 50
|
|
12
|
+
_trace = True
|
|
13
|
+
_visible = False
|
|
14
|
+
|
|
15
|
+
def makeGlow():
|
|
16
|
+
global _visible
|
|
17
|
+
display.set_pixel(2, 2, 9)
|
|
18
|
+
_visible = True
|
|
19
|
+
|
|
20
|
+
def clear():
|
|
21
|
+
display.clear()
|
|
22
|
+
|
|
23
|
+
def forward():
|
|
24
|
+
_forward(1)
|
|
25
|
+
|
|
26
|
+
def back():
|
|
27
|
+
_forward(-1)
|
|
28
|
+
|
|
29
|
+
def right(angle):
|
|
30
|
+
global _dir
|
|
31
|
+
_dir = (_dir + angle) % 360
|
|
32
|
+
|
|
33
|
+
def left(angle):
|
|
34
|
+
right(-angle)
|
|
35
|
+
|
|
36
|
+
def setPos(x, y):
|
|
37
|
+
global _x, _y
|
|
38
|
+
_x = x
|
|
39
|
+
_y = y
|
|
40
|
+
_render()
|
|
41
|
+
|
|
42
|
+
def getPos():
|
|
43
|
+
return _x, _y
|
|
44
|
+
|
|
45
|
+
def setSpeed(speed):
|
|
46
|
+
global _speed
|
|
47
|
+
_speed = speed
|
|
48
|
+
|
|
49
|
+
def showTrace(enable):
|
|
50
|
+
global _trace
|
|
51
|
+
_trace = enable
|
|
52
|
+
|
|
53
|
+
def isLit():
|
|
54
|
+
return (display.get_pixel(_x + 2, 4 - (_y + 2)) == 9)
|
|
55
|
+
|
|
56
|
+
def _forward(s):
|
|
57
|
+
global _x, _y
|
|
58
|
+
sleep(2000 - _speed * 20)
|
|
59
|
+
d = _dir // 45
|
|
60
|
+
if d in [1, 2, 3]:
|
|
61
|
+
_x += s
|
|
62
|
+
if d in [5, 6, 7]:
|
|
63
|
+
_x -= s
|
|
64
|
+
if d in [0, 1, 7]:
|
|
65
|
+
_y += s
|
|
66
|
+
if d in [3, 4, 5]:
|
|
67
|
+
_y -= s
|
|
68
|
+
_render()
|
|
69
|
+
|
|
70
|
+
def _render():
|
|
71
|
+
if not _visible:
|
|
72
|
+
print("Use \"makeGlow()\" to create a Glow.")
|
|
73
|
+
raise Exception("Glow not initialized.")
|
|
74
|
+
if not _trace:
|
|
75
|
+
display.clear()
|
|
76
|
+
if -2 <= _x <= 2 and -2 <= _y <= 2:
|
|
77
|
+
display.set_pixel(_x + 2, 4 - (_y + 2), 9)
|