Advertisement
Guest User

Untitled

a guest
Feb 24th, 2020
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.32 KB | None | 0 0
  1. #include <string>
  2. #include <cstdio>
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. #include "mbed.h"
  8. #include "SHA256.h"
  9.  
  10.  
  11. //Photointerrupter input pins
  12. #define I1pin D3
  13. #define I2pin D6
  14. #define I3pin D5
  15.  
  16. //Incremental encoder input pins
  17. #define CHApin D12
  18. #define CHBpin D11
  19.  
  20. //Motor Drive output pins //Mask in output byte
  21. #define L1Lpin D1 //0x01
  22. #define L1Hpin A3 //0x02
  23. #define L2Lpin D0 //0x04
  24. #define L2Hpin A6 //0x08
  25. #define L3Lpin D10 //0x10
  26. #define L3Hpin D2 //0x20
  27.  
  28. #define PWMpin D9
  29.  
  30. //Motor current sense
  31. #define MCSPpin A1
  32. #define MCSNpin A0
  33.  
  34. //Test outputs
  35. #define TP0pin D4
  36. #define TP1pin D13
  37. #define TP2pin A2
  38.  
  39. #define PWM_PERIOD 2000
  40. #define HASH_INTERVAL 100000
  41.  
  42. //Mapping from sequential drive states to motor phase outputs
  43. /*
  44. State L1 L2 L3
  45. 0 H - L
  46. 1 - H L
  47. 2 L H -
  48. 3 L - H
  49. 4 - L H
  50. 5 H L -
  51. 6 - - -
  52. 7 - - -
  53. */
  54. //Drive state to output table
  55. const int8_t driveTable[] = {0x12,0x18,0x09,0x21,0x24,0x06,0x00,0x00};
  56.  
  57. //Mapping from interrupter inputs to sequential rotor states. 0x00 and 0x07 are not valid
  58. const int8_t stateMap[] = {0x07,0x05,0x03,0x04,0x01,0x00,0x02,0x07};
  59. //const int8_t stateMap[] = {0x07,0x01,0x03,0x02,0x05,0x00,0x04,0x07}; //Alternative if phase order of input or drive is reversed
  60.  
  61. //Phase lead to make motor spin
  62. const int8_t lead = 2; //2 for forwards, -2 for backwards
  63.  
  64. int8_t orState = 0; //Rotot offset at motor state 0
  65. int8_t rotorState;
  66. int8_t rotorStateOld = 0;
  67.  
  68. uint8_t maxVelocity = 20;
  69.  
  70. long long revolutions = 0;
  71. long long unsigned globalKey = 0;
  72. Mutex globalKey_mutex;
  73.  
  74. Thread motorCtrlT(osPriorityNormal, 1024);
  75.  
  76. //Status LED
  77. DigitalOut led1(LED1);
  78.  
  79. //Photointerrupter inputs
  80. InterruptIn I1(I1pin);
  81. InterruptIn I2(I2pin);
  82. InterruptIn I3(I3pin);
  83.  
  84. //Motor Drive outputs
  85. DigitalOut L1L(L1Lpin);
  86. DigitalOut L1H(L1Hpin);
  87. DigitalOut L2L(L2Lpin);
  88. DigitalOut L2H(L2Hpin);
  89. DigitalOut L3L(L3Lpin);
  90. DigitalOut L3H(L3Hpin);
  91.  
  92. DigitalOut TP1(TP1pin);
  93. PwmOut MotorPWM(PWMpin);
  94.  
  95.  
  96.  
  97. typedef struct {
  98. string message;
  99. } mail_t;
  100.  
  101. Mail<mail_t, 16> mail_box;
  102.  
  103. RawSerial pc(SERIAL_TX, SERIAL_RX);
  104. Queue<void, 8> inCharQ;
  105. void serialISR(){
  106. uint8_t newChar = pc.getc();
  107. inCharQ.put((void*)(size_t)newChar);
  108. }
  109.  
  110.  
  111. //Set a given drive state
  112. void motorOut(int8_t driveState){
  113.  
  114. //Lookup the output byte from the drive state.
  115. int8_t driveOut = driveTable[driveState & 0x07];
  116.  
  117. //Turn off first
  118. if (~driveOut & 0x01) L1L = 0;
  119. if (~driveOut & 0x02) L1H = 1;
  120. if (~driveOut & 0x04) L2L = 0;
  121. if (~driveOut & 0x08) L2H = 1;
  122. if (~driveOut & 0x10) L3L = 0;
  123. if (~driveOut & 0x20) L3H = 1;
  124.  
  125. //Then turn on
  126. if (driveOut & 0x01) L1L = 1;
  127. if (driveOut & 0x02) L1H = 0;
  128. if (driveOut & 0x04) L2L = 1;
  129. if (driveOut & 0x08) L2H = 0;
  130. if (driveOut & 0x10) L3L = 1;
  131. if (driveOut & 0x20) L3H = 0;
  132. }
  133.  
  134. //Convert photointerrupter inputs to a rotor state
  135. inline int8_t readRotorState(){
  136. return stateMap[I1 + 2*I2 + 4*I3];
  137. }
  138.  
  139. //Basic synchronisation routine
  140. int8_t motorHome() {
  141. //Put the motor in drive state 0 and wait for it to stabilise
  142. motorOut(0);
  143. ThisThread::sleep_for(2000);
  144.  
  145. //Get the rotor state
  146. return readRotorState();
  147. }
  148.  
  149. void sendMessage(string message) {
  150. mail_t *mail = mail_box.alloc();
  151. mail->message = message;
  152. mail_box.put(mail);
  153. }
  154.  
  155. void motorInterruptHandler() {
  156. rotorState = readRotorState();
  157. int8_t direction = rotorState - rotorStateOld;
  158. motorOut((rotorState-orState+lead+6)%6); //+6 to make sure the remainder is positive
  159. if (rotorState == 5 && rotorStateOld == 0) {
  160. revolutions++;
  161. }
  162. else if (rotorState == 0 && rotorStateOld == 5) {
  163. revolutions--;
  164. }
  165. //if (intState == 4 && intStateOld == 3) TP1 = !TP1;
  166. rotorStateOld = rotorState;
  167. //sendMessage(to_string(revolutions));
  168. // if (rotorState % 6 == 0) {
  169. // sendMessage(to_string(revolutions));
  170. // }
  171. }
  172.  
  173. void messageThread(void) {
  174. while(true) {
  175. osEvent evt = mail_box.get();
  176. if (evt.status == osEventMail) {
  177. mail_t *mail = (mail_t*)evt.value.p;
  178. pc.printf("%s\n\r", mail->message.c_str());
  179. mail_box.free(mail);
  180. }
  181. }
  182. }
  183.  
  184. void commandThread(void) {
  185. pc.attach(&serialISR);
  186. string command;
  187.  
  188. while(1) {
  189. osEvent newEvent = inCharQ.get();
  190. char newChar = (char)(size_t)newEvent.value.p;
  191. char char_array[command.size() + 1];
  192. char message[64];
  193. strlcpy(char_array, command.c_str(), command.size() + 1);
  194. if (newChar == '\r') {
  195. if (command.size() > 0) {
  196. // Setting Key for Bitcoin Mining
  197. if (command[0] == 'K') {
  198. uint64_t key;
  199. sscanf(char_array, "%*c%16llx", &key);
  200. globalKey_mutex.lock();
  201. globalKey = key;
  202. globalKey_mutex.unlock();
  203. snprintf(message, sizeof(message), "Updating hash key to %16llu", key);
  204. sendMessage(message);
  205. }
  206. // Setting Duty Cycle
  207. else if (command[0] == 'P') {
  208. int key;
  209. sscanf(char_array, "%*c%d", &key);
  210. if (key < 0 || key > 100) {
  211. sendMessage("Invalid pulse width, please specify a value between 0 and 100");
  212. } else {
  213. MotorPWM.pulsewidth_us(0.01 * key * PWM_PERIOD);
  214. snprintf(message, sizeof(message), "Updating pulse width to %d", key);
  215. sendMessage(message);
  216. }
  217. }
  218. // Setting maximum velocity
  219. else if (command[0] == 'V') {
  220. uint8_t velocity;
  221. sscanf(char_array, "%*c%8s", &velocity);
  222. snprintf(message, sizeof(message), "Setting max velocity to %d", velocity);
  223. sendMessage(message);
  224.  
  225. }
  226. else {
  227. sendMessage("Invalid command, please try");
  228. }
  229. }
  230.  
  231. command = "";
  232. } else {
  233. command.push_back(newChar);
  234. sendMessage("Entering command: " + command);
  235. }
  236. }
  237.  
  238. }
  239.  
  240. void bitcoinThreat(void) {
  241. uint8_t sequence[] = {0x45,0x6D,0x62,0x65,0x64,0x64,0x65,0x64,
  242. 0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x73,
  243. 0x20,0x61,0x72,0x65,0x20,0x66,0x75,0x6E,
  244. 0x20,0x61,0x6E,0x64,0x20,0x64,0x6F,0x20,
  245. 0x61,0x77,0x65,0x73,0x6F,0x6D,0x65,0x20,
  246. 0x74,0x68,0x69,0x6E,0x67,0x73,0x21,0x20,
  247. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  248. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  249. uint64_t* key = (uint64_t*)&sequence[48];
  250. uint64_t* nonce = (uint64_t*)&sequence[56];
  251. uint8_t hash[32];
  252.  
  253. Timer t;
  254. SHA256 sha256;
  255.  
  256. t.start();
  257. while(true) {
  258. if (*nonce % HASH_INTERVAL == 0) {
  259. t.stop();
  260. float time_elapsed = t.read();
  261. float hash_speed = HASH_INTERVAL / time_elapsed;
  262. sendMessage("Hash speed: " + to_string(hash_speed) + " H/s");
  263. t.reset();
  264. t.start();
  265. }
  266. globalKey_mutex.lock();
  267. *key = globalKey;
  268. globalKey_mutex.unlock();
  269. sha256.computeHash(hash, sequence, 64);
  270. if (hash[0] == 0 && hash[1] == 0) {
  271. sendMessage("Found hash with nonce: " + to_string(*nonce));
  272. }
  273. *nonce += 1;
  274. }
  275. }
  276.  
  277. void motorCtrlTick() {
  278. motorCtrlT.flags_set(0x1);
  279. }
  280.  
  281. void motorCtrlFn() {
  282. Ticker motorCtrlTicker;
  283. motorCtrlTicker.attach_us(&motorCtrlTick, 100000);
  284.  
  285. long long prevRevs;
  286. uint8_t count;
  287. Timer t;
  288.  
  289. t.start();
  290.  
  291. while(1) {
  292. motorCtrlT.signal_wait(0x1);
  293. count++;
  294. if (count == 10) {
  295. float time_elapsed = t.read();
  296. t.stop();
  297. count = 0;
  298. long velocity = revolutions - prevRevs / time_elapsed;
  299. sendMessage("Velocity: " + to_string(velocity) + " rev/s");
  300. prevRevs = revolutions;
  301. t.reset();
  302. t.start();
  303. }
  304. }
  305. }
  306.  
  307. //Main
  308. int main() {
  309. MotorPWM.period_us(PWM_PERIOD);
  310. MotorPWM.pulsewidth_us(0.5*PWM_PERIOD);
  311. motorInterruptHandler();
  312.  
  313. pc.printf("Hello\n\r");
  314.  
  315. //Run the motor synchronisation
  316. orState = motorHome();
  317. pc.printf("Rotor origin: %x\n\r",orState);
  318. //orState is subtracted from future rotor state inputs to align rotor and motor states
  319.  
  320. I1.rise(&motorInterruptHandler);
  321. I2.rise(&motorInterruptHandler);
  322. I3.rise(&motorInterruptHandler);
  323. I1.fall(&motorInterruptHandler);
  324. I2.fall(&motorInterruptHandler);
  325. I3.fall(&motorInterruptHandler);
  326.  
  327. Thread t1(osPriorityLow);
  328. t1.start(bitcoinThreat);
  329.  
  330. Thread t2;
  331. t2.start(messageThread);
  332.  
  333. Thread t3;
  334. t3.start(commandThread);
  335.  
  336. motorCtrlT.start(motorCtrlFn);
  337.  
  338. while (1) {
  339. ThisThread::sleep_for(1000);
  340. }
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement