关于Arduino UNO软复位后的问题提问

对于Arduino,可以用

void(* resetFunc)(void) = 0;
......
resetFunc();

进行软复位。

但是,本人的UNO进行过这一操作后出现异常复位的现象。

laser.h如下:

#include "Arduino.h"
#include 
#include 
#define pi 3.14
#define ir1 16738455
#define ir2 16750695
#define ir3 16756815
#define ir4 16724175
#define ir5 16718055
#define ir6 16743045
#define ir7 16716015
#define ir8 16726215
#define ir9 16734885
#define ir0 16730805
#define irj 16732845
#define irx 16728765
#define longpress 4294967295
#define irok 16712445
#define left 16720605
#define right 16761405
#define down 16754775
#define up 16736925
using namespace std;

void laserSet(int,int,int);
void trans(float fa[], short int si[]);
void circle(short int x[], short int y[], float r);
void ellipse(short int x[], short int y[], float a, float b);
void heart(short x[], short y[], float a);
float serialIn(const char*);
void constout(short a[], short b[]);
void zoomout(short a[], short b[], float c);
void rotout(short a[], short b[], float c);
void rzout(short a[], short b[], float c, float d);
char irmode(int);
float irin(int,const char*);
short shape(const char* instream, int pin);
void t_ellipse(const char* instream, int pin, short x[], short y[]);
void t_circle(const char* instream, int pin, short x[], short y[]);
void t_heart(const char* instream, int pin, short x[], short y[]);

laser.cpp如下:

#include "laser.h"
void laserSet(int xpin,int ypin,int kpin) {
  TCCR1B = TCCR1B & 0b11111000 | 1;//调整系统时钟
  pinMode(xpin, OUTPUT);//x 连9
  pinMode(ypin, OUTPUT);//y 连10
  pinMode(kpin, OUTPUT); //laser on/off,连4
  pinMode(13, OUTPUT);
  digitalWrite(kpin, LOW);//关闭激光输出
  digitalWrite(13, LOW);
  Serial.begin(115200);
  while (Serial.read() > 0);
}

void trans(float fa[], short int si[]) {//将浮点数据转为整形(0-255)
  for (int i = 0; i < 90; i++) 
    si[i] = (short int)(fa[i]) + 128;
}

void circle(short int x[], short int y[], float r) {//生成圆坐标并转化,可自定义半径
	float m[90], n[90];
  for (int i = 0; i < 90; i++) {
    m[i] = r * cos((2 * pi / 90) * i);
    n[i] = r * sin((2 * pi / 90) * i);
  }
  trans(m, x);
  trans(n, y);
  delete []m;
  delete []n;
}

void ellipse(short int x[], short int y[],float a, float b) {//生成椭圆坐标并转化,可自定义a、b
	float m[90], n[90];
  for (int i = 0; i < 90; i++) {
    m[i] = a * cos(2 * (i * pi) / 90);
    n[i] = b * sin(2 * (i * pi) / 90);
  }
  trans(m, x);
  trans(n, y);
  delete []m;
  delete []n;
}

void heart(short x[], short y[], float a) {
	float m[90], n[90];
	for (unsigned short i = 0; i < 90; i++) {
		m[i] = a * acos(sin(i*pi / 45))*cos(i*pi / 45);
		n[i] = a * acos(sin(i*pi / 45))*sin(i*pi / 45);
	}
	trans(m, x);
	trans(n, y);
	delete[]m;
	delete[]n;
}

float serialIn(const char* a) {
  float b;
  Serial.print(a);
  while (Serial.available() == 0);
  b = Serial.parseFloat();
  Serial.println(b);
  Serial.flush();
  return b;
}

void constout(short a[], short b[]) {
  for (int i = 0; i < 90; i++) {
    analogWrite(9, a[i]);
    analogWrite(10, b[i]);
  }
}

void zoomout(short a[], short b[], float c) {
  for (float t = c; t <= 1; t += 0.1) {
    for (int i = 0; i < 90; i++) {
      analogWrite(9, (int)((a[i] - 128)*t) + 128);
      analogWrite(10, (int)((b[i] - 128)*t) + 128);
    }
    analogWrite(9, (int)((a[89] - 128)*t) + 128);
    analogWrite(10, (int)((b[89] - 128)*t) + 128);
    delay(10);
  }
}

void rotout(short a[], short b[], float c) {
  for (float t = 0; t <= 2 * pi / c; t++) {
    for (int i = 0; i < 90; i++) {
      analogWrite(9, (int)((a[i] - 128)*cos(t * c) + (b[i] - 128)*sin(t * c)) + 128);
      analogWrite(10, (int)((b[i] - 128)*cos(t * c) - (a[i] - 128)*sin(t * c)) + 128);
    }
  }
}

void rzout(short a[], short b[], float c, float d) {
  for (float t = c; t <= 1; t += 0.1) {
    for (float p = 0; p <= 2 * pi / d; p++) {
      for (int i = 0; i < 90; i++) {
        analogWrite(9, (int)(((a[i] - 128)*t)*cos(p * d) + ((b[i] - 128)*t)*sin(p * d)) + 128);
        analogWrite(10, (int)(((b[i] - 128)*t)*cos(p * d) - ((a[i] - 128)*t)*sin(p * d)) + 128);
      }
    }
  }
}

char irmode(int pin) {//ir请连11
  IRrecv irrecv(pin);
  decode_results results;
  irrecv.enableIRIn();
  while (!irrecv.decode(&results));
  if (irrecv.decode(&results)) {
    if (results.value == ir1)
      return '1';
    if (results.value == ir2)
      return '2';
    if (results.value == ir3)
      return '3';
    if (results.value == ir4)
      return '4';
    if (results.value == ir5)
      return '5';
    if (results.value == ir6)
      return '6';
    if (results.value == ir7)
      return '7';
    if (results.value == ir8)
      return '8';
    if (results.value == ir9)
      return '9';
    if (results.value == ir0)
      return '0';
    if (results.value == irx)
      return '.';
    if (results.value == irok)
      return '\0';
  }
}

float irin(int pin,const char* item) {
	Serial.print(item);
  short i = 0;
  char buf[10];
  while (i < 9) {
    buf[i] = irmode(pin);
    if (buf[i] == '\0')
      break;
    i++;
  }
  return atof(buf);
}

short shape(const char* instream,int pin) {
	Serial.println("请输入您的图形模式。(椭圆为1,圆为2,心形线为3)");
	short temporary = 0;
	if (strcmp(instream, "Serial") == 0) {
		while (Serial.available() == 0);
		temporary = Serial.parseInt();
	}
	if (strcmp(instream, "IR") == 0) {
		char temp[2] = { '0','\0' };
		temp[0] = irmode(pin);
		temporary = atoi(temp);
	}
	Serial.print(temporary);
	Serial.print("、");
	if (temporary == 1)
		Serial.println("椭圆");
	if (temporary == 2)
		Serial.println("圆");
	if (temporary == 3)
		Serial.println("心形线");
	if (temporary == 1 || temporary == 2 || temporary == 3)
		return temporary;
	else
		return (-1);
}

void t_ellipse(const char* instream, int pin,short x[], short y[]) {
	Serial.println("OK!");
eerr_pos:float a, b = 0;
	if (strcmp(instream, "Serial") == 0) {
		a = serialIn("x轴半径 a=");
		b = serialIn("y轴半径 b=");
	}
	if (strcmp(instream, "IR") == 0) {
		a = irin(pin,"x轴半径 a=");
		b = irin(pin,"y轴半径 b=");
	}
	if (a < 0 || b < 0 || a>128 || b>128) {
		Serial.println("超出范围!");
		goto eerr_pos;
	}
	ellipse(x, y, a, b);
}

void t_circle(const char* instream, int pin, short x[], short y[]) {
	Serial.println("OK!");
cerr_pos:float r = 0;
	if(strcmp(instream, "Serial") == 0)
		r = serialIn("半径 r=");
	if (strcmp(instream, "IR") == 0)
		r = irin(pin, "半径 r=");
	if (r < 0 || r>128) {
		Serial.println("超出范围!");
		goto cerr_pos;
	}
	circle(x, y, r);
}

void t_heart(const char* instream, int pin, short x[], short y[]) {
	Serial.println("OK!");
herr_pos:float a = 0;
	if (strcmp(instream, "Serial") == 0)
		a = serialIn("比例系数(0-36) a=");
	if (strcmp(instream, "IR") == 0)
		a = irin(pin, "比例系数(0-36) a=");
	if (a <= 0 || a > 36) {
		Serial.println("超出范围!");
		goto herr_pos;
	}
	heart(x, y, a);
}

.ino文件如下:

#include //自定义库文件
//先指定输入方式,使用串口请输入"Serial",使用ir请输入"IR"
//输出椭圆用serial的1或者ir的1
//输出圆用serial的2或者ir的2
//输出心形线用serial的3或者ir的3
short x[90], y[90];//x,y坐标组合
float beta = 1;//放大率beta
float omega = 0;//旋转角速度omega
const int irpin = 11;//可更改,ir初始连11
void(* resetFunc)(void) = 0;//虚拟复位
void setup() {
  // put your setup code here, to run once:
  laserSet(9, 10, 4);//可更改,x->9,y->10,key->4
  Serial.println("==================================");
  Serial.println("欢迎使用激光表演系统!");
  Serial.println("激光输出状态:关闭。");
  Serial.println("当板载LED(L,13)常亮时,需注意激光输出!");
  String imodestr = "";//指示输入方式
  char imode[10];
istream_pos: short buff = 0;//存图形
  Serial.println("请指定输入方式。(Serial或IR)");
  while (Serial.available() == 0);
  imodestr = Serial.readString();
  strcpy(imode, imodestr.c_str());
  Serial.println(imodestr);
  if (strcmp(imode, "Serial") != 0 && strcmp(imode, "IR") != 0) {
    Serial.println("错误!");
    goto istream_pos;
  }
  if (strcmp(imode, "IR") == 0)
    Serial.println("小数点请用星号键输入。");
spos: buff = shape(imode, irpin);
  if (buff == (-1)) {
    Serial.println("指令错误!");
    goto spos;
  }
  if (buff == 1) {
    t_ellipse(imode, irpin, x, y);//异常复位点
    while (Serial.read() > 0);
  }
  if (buff == 2) {
    t_circle(imode, irpin, x, y);//异常复位点
    while (Serial.read() > 0);
  }
  if (buff == 3) {
    t_heart(imode, irpin, x, y);//异常复位点
    while (Serial.read() > 0);
  }
bpos: if (strcmp(imode, "Serial") == 0)
    beta = serialIn("最小缩放倍率(<1) beta=");
  if (strcmp(imode, "IR") == 0)
    beta = irin(irpin, "最小缩放倍率(<1) beta=");
  if (beta <= 0 || beta > 1) {
    Serial.println("指令错误!");
    goto bpos;
  }
opos: if (strcmp(imode, "Serial") == 0)
    omega = serialIn("旋转角速度(rad/ms) omega=");
  if (strcmp(imode, "IR") == 0)
    omega = irin(irpin, "旋转角速度(rad/ms) omega=");
  if (omega < 0 || omega > 1) {
    Serial.println("指令错误!");
    goto opos;
  }
  Serial.print("若想要重新输入图形,");
  Serial.print("按任意键并按回车或");
  Serial.println("使用遥控器按任意键");
  Serial.println("开启激光输出!注意安全!");
  while (Serial.read() > 0);
  digitalWrite(13, HIGH);
  digitalWrite(4, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:
  bool key = false;
  IRrecv irinstream(irpin);
  decode_results res;
  irinstream.enableIRIn();
  if (Serial.available() != 0 || irinstream.decode(&res))
    key = true;
  if (!key) {
    digitalWrite(13, HIGH);
    if (beta == 1) {
      if (omega == 0)
        constout(x, y);
      else
        rotout(x, y, omega);
    }
    if (beta > 0 && beta < 1 && omega == 0)
      zoomout(x, y, beta);
    if (beta > 0 && beta < 1 && omega != 0)
      rzout(x, y, beta, omega);
  }
  if (key) {
    digitalWrite(4, LOW);
    digitalWrite(13, LOW);
    resetFunc();
  }
  digitalWrite(4, LOW);
  digitalWrite(13, LOW);
}

请问是什么原因造成的?求各位大神指点!!

你可能感兴趣的:(关于Arduino UNO软复位后的问题提问)