Arduino利用键盘矩阵实现计算器

这篇具有很好参考价值的文章主要介绍了Arduino利用键盘矩阵实现计算器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

运行结果演示

Arduino利用键盘矩阵实现计算器

基本思路

基本结构

Arduino利用键盘矩阵实现计算器

键盘数据读入

运算实现原理

为了实现复杂的四则运算,首先需要考虑的是算数符号以及括号的优先级。具体实现流程如下:

  1. 如果是数字,则压入操作数栈中
  2. 如果是运算符,则有两种情况:
    ①如果运算符栈为空,则将其压入运算符栈中
    ②如果不为空,则比较其与运算符栈中的优先级,如果大于则压入栈中,否则从操作数栈中取出两个数进行相应计算
  3. 如果为* ) * ,取出操作数栈中两个数与运算符栈中运算符计算,结果压入操作数栈中。直至遇到* )*
  4. 将剩余操作数与运算符进行运算,直至操作数栈为空

实现准备

为了实现运算,需要准备简单的栈结构及其基本操作:

/*
  简易栈实现
*/
int stackNum[255] = { 0 };
int stackNumTopIndex = -1;

char stackChar[255] = {};
int stackCharTopIndex = -1;

void pushNumStack(int num) {
	stackNum[++stackNumTopIndex] = num;
}

void pushCharStack(char op)
{
	stackChar[++stackCharTopIndex] = op;
}

bool isEmptyOfNumStack()
{
	return stackNumTopIndex == -1;
}

bool isEmptyOfCharStack()
{
	return stackCharTopIndex == -1;
}

int popNumStack() {
	if (isEmptyOfNumStack()) {
		return -1;
	}
	return stackNum[stackNumTopIndex--];
}

char popCharStack()
{
	if (isEmptyOfCharStack()) {
		return '!';
	}
	return stackChar[stackCharTopIndex--];
}

int peekNumStack()
{
	return stackNum[stackNumTopIndex];
}

int peekCharStack() 
{
	return stackChar[stackCharTopIndex];
}

接着,实现对数据的一些基本功能函数

/*
 * 数据处理
*/

//获取算数符号优先级
int getPriority(char op)
{
	int level = 0;

	switch (op)
	{
	case '(':
		level = 1;
		break;
	case '+':
	case '-':
		level = 2;
		break;
	case '*':
	case '/':
		level = 3;
		break;
	default:
		break;
	}

	return level;
}

//是否是算数运算符
bool isOperator(char op) 
{
	if ( op== '+' || op == '-' || op == '*' || op == '/') {
		return true;
	}
	else {
		return false;
	}
}

//进行相应计算
int Calculate(int lNum, char op, int rNum)
{
	int result = 0;

	switch (op)
	{
	case '+':
		result = lNum + rNum;
		break;
	case '-':
		result = lNum - rNum;
		break;
	case '*':
		result = lNum * rNum;
		break;
	case '/':
		if (rNum != 0) {
			result = lNum / rNum;
		}
		break;
	default:
		break;
	}
	return result;
}

表达式运算代码

int getNum(string str) {

	int result = 0;
	int lNum, rNum;
	int num = 0;
	char op;


	for (int i = 0; i < str.length();) {
		if (isdigit(str[i])) {
			//读入之后字符,判断是否为数字
			num = 0;
			while (isdigit(str[i])) {
				num = num * 10 + (str[i] - '0');
				i++;
			}
			pushNumStack(num);
		}
		else if (str[i] == '(') {
			pushCharStack(str[i++]);
		}
		else if (isOperator(str[i])) {    //运算符
			//符号栈为空,将运算符压入栈中
			if (isEmptyOfCharStack()) {
				pushCharStack(str[i++]);
			}
			else {
				while (!isEmptyOfCharStack()) {
					//优先级低于或等于进行计算,得数压入数据栈中
					if (getPriority(str[i]) <= getPriority(peekCharStack())) {
						rNum = popNumStack();
						lNum = popNumStack();
						op = popCharStack();
						pushNumStack(Calculate(lNum,op,rNum));
					}else {
						break;
					}
				}
				pushCharStack(str[i++]);
			}
		}
		else if (str[i] == ')') {
			while (peekCharStack() != '(') {
				op = popCharStack();   //取出栈顶操作符
				int rNum = popNumStack();
				int lNum = popNumStack();
				result = 0;
				result = Calculate(lNum, op, rNum);
				pushNumStack(result);
			}
			popCharStack();  //弹出(
			i++;
		}
	}
	
	while (!isEmptyOfCharStack())
	{
		op = popCharStack();
		int rNum = popNumStack();
		int lNum = popNumStack();

		result = 0;
		result = Calculate(lNum, op, rNum);
		pushNumStack(result);
 	}
	return popNumStack();
}

完整代码

//引入键盘处理库 --> 第三方库
#include <Keypad.h>

/*
  简易栈实现
*/
int stackNum[255] = { 0 };
int stackNumTopIndex = -1;

char stackChar[255] = {};
int stackCharTopIndex = -1;

void pushNumStack(int num) {
  stackNum[++stackNumTopIndex] = num;
}

void pushCharStack(char op)
{
  stackChar[++stackCharTopIndex] = op;
}


bool isEmptyOfNumStack()
{
  return stackNumTopIndex == -1;
}

bool isEmptyOfCharStack()
{
  return stackCharTopIndex == -1;
}

int popNumStack() {
  if (isEmptyOfNumStack()) {
    return -1;
  }
  return stackNum[stackNumTopIndex--];
}

char popCharStack()
{
  if (isEmptyOfCharStack()) {
    return '!';
  }
  return stackChar[stackCharTopIndex--];
}

int peekNumStack()
{
  return stackNum[stackNumTopIndex];
}

int peekCharStack() 
{
  return stackChar[stackCharTopIndex];
}


/*
 * 数据处理
*/

//获取算数符号优先级
int getPriority(char op)
{
  int level = 0;

  switch (op)
  {
  case '(':
    level = 1;
    break;
  case '+':
  case '-':
    level = 2;
    break;
  case '*':
  case '/':
    level = 3;
    break;
  default:
    break;
  }

  return level;
}

//是否是算数运算符
bool isOperator(char op) 
{
  if ( op== '+' || op == '-' || op == '*' || op == '/') {
    return true;
  }
  else {
    return false;
  }
}

//进行相应计算
int Calculate(int lNum, char op, int rNum)
{
  int result = 0;

  switch (op)
  {
  case '+':
    result = lNum + rNum;
    break;
  case '-':
    result = lNum - rNum;
    break;
  case '*':
    result = lNum * rNum;
    break;
  case '/':
    if (rNum != 0) {
      result = lNum / rNum;
    }
    break;
  default:
    break;
  }
  return result;
}


//字符串数字拼接
/*
  拆分表达式并计算
*/
int getNum(String str) {

  int result = 0;
  int lNum, rNum;
  int num = 0;
  char op;


  for (int i = 0; i < str.length();) {
    if (isdigit(str[i])) {
      //读入之后字符,判断是否为数字
      num = 0;
      while (isdigit(str[i])) {
        num = num * 10 + (str[i] - '0');
        i++;
      }
      pushNumStack(num);
    }
    else if (str[i] == '(') {
      pushCharStack(str[i++]);
    }
    else if (isOperator(str[i])) {    //运算符
      //符号栈为空,将运算符压入栈中
      if (isEmptyOfCharStack()) {
        pushCharStack(str[i++]);
      }
      else {
        while (!isEmptyOfCharStack()) {
          //优先级低于或等于进行计算,得数压入数据栈中
          if (getPriority(str[i]) <= getPriority(peekCharStack())) {
            rNum = popNumStack();
            lNum = popNumStack();
            op = popCharStack();
            pushNumStack(Calculate(lNum,op,rNum));
          }else {
            break;
          }
        }
        pushCharStack(str[i++]);
      }
    }
    else if (str[i] == ')') {
      while (peekCharStack() != '(') {
        op = popCharStack();   //取出栈顶操作符
        int rNum = popNumStack();
        int lNum = popNumStack();
        result = 0;
        result = Calculate(lNum, op, rNum);
        pushNumStack(result);
      }
      popCharStack();  //弹出(
      i++;
    }
  }
  

  while (!isEmptyOfCharStack())
  {
    op = popCharStack();
    int rNum = popNumStack();
    int lNum = popNumStack();

    result = 0;
    result = Calculate(lNum, op, rNum);
    pushNumStack(result);
  }
  return popNumStack();
}


//读取用户输入值
String getExpression(){
  String res = "";

  //读取串口监视器中表达式
  while(true){
    int in = Serial.read();
    if(in != -1){
      if(in == '='){
        break;
      }else{
        res = res +(char)in; 
      } 
    }
  }
  return res;
}


//矩阵键盘设置

const byte rows = 4; //four rows
const byte cols = 4; //three columns
char keys[rows][cols] = {
  {'1','2','3','+'},
  {'4','5','6','-'},
  {'7','8','9','*'},
  {'D','0','=','/'}
};
byte rowPins[rows] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[cols] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );



String getExpressionFromKeyBoard(){
  String res = "";
  while(true){
    char key = keypad.getKey();   //获取当前输入字符 
    if(key && key != '=' && key != 'D'){
       res += key;
       Serial.print("当前输入表达式:");
      Serial.println(res);
    }else if(key && key == '='){
       break;
    }else if(key && key == 'D'){
      res = res.substring(0,res.length()-1);
      Serial.print("当前输入表达式:");
      Serial.println(res);
    }
  }
  Serial.println();
  return res;
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  String expression = getExpressionFromKeyBoard();
  Serial.print("当前表达式:");
  Serial.println(expression);

  Serial.print("运算结果为:");
  int res = getNum(expression);
  Serial.println(res);
}

总结

此代码仅仅对于算数计算做出了详细解释,对于Arduino与矩阵之间的连接电路以及按键读取未做出详细解释。
其相应的接线方式可参照代码中对应接口进行连接。同时,键盘键位有限,不能将本程序完全演示完毕(可包含括号运算,支持复杂算术运算)
文章来源地址https://www.toymoban.com/news/detail-409710.html

到了这里,关于Arduino利用键盘矩阵实现计算器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 龙芯1b(LS1B200)使用LVGL7.0.1组件 按钮矩阵 实现简易计算器

    需求:通过按钮点击实现加减乘除的简易计算器。 1.我们使用矩阵按钮(lv_ btnmatrix )快速创建布局,文本框( lv_textarea)显示结果 。 2.在按钮回调中将点击结果加入文本框上显示。 矩阵按钮相对于普通按钮: • 对于基于网格的按钮布局,按钮矩阵更易于使用。 • 每个按钮矩阵

    2024年02月05日
    浏览(42)
  • 矩阵计算器

    摘要:在本报告中介绍了一套图形界面的矩阵计算器的的想法与需求分析、设计、实现,测试和改进。在想法与需求分析中介绍了我研发此程序的契机和原因。在设计中介绍了对该程序的设计,以及如何实现。实现中介绍了对关键代码的分析和解释。测试以图片的形式证明了

    2024年02月08日
    浏览(45)
  • Proteus仿真--12864LCD显示计算器键盘按键实验(仿真文件+程序)

    本文主要介绍基于51单片机的12864LCD液晶显示电话拨号键盘按键实验(完整仿真源文件及代码见文末链接) 仿真图如下 本设计主要介绍计算器键盘仿真,按键按下后在12864液晶上显示对应按键键值 仿真运行视频 Proteus仿真--12864LCD显示计算器键盘按键实验 附完整Proteus仿真资料

    2024年02月06日
    浏览(38)
  • 卡西欧计算器矩阵求逆

    记录一下,防止忘记  1 按开机键 打开计算器  2 按 菜单设置键  进去计算模式选择模块  3 按“ 4 ”选择矩阵运算  4 有四个矩阵可以编辑 选择按 4 编辑矩阵D  5 输入矩阵的行数 我按了3 6 输入矩阵的列数 我按了 3  7 建了一个3*3空矩阵   输入第一个数 1÷2 然后按“=”键完

    2024年02月03日
    浏览(43)
  • 科学计算器如何求矩阵的逆

    大学本科买了四年的计算器不会求逆,到了研究生了好好研究下这个功能,终于终于会用了,以往 对着那个矩阵功能都发懵😂,记录一下这个史诗无敌隐藏功能 要是早知道本科线代就轻松了,不过现在知道也不晚,起码还有个高工考试hhh

    2023年04月21日
    浏览(32)
  • 利用Python解决利率相关计算问题(利率计算器):本金翻倍,定期取款,多重利率,通货膨胀等问题

    目录 一.原理 二.实际问题举例 多利率问题  存款与本金翻倍  存款与定期取款   存款与通货膨胀 利用python中的for循环或者while循环来计算利率或者解决复利问题。 其中涉及到不同场景下的不同利率问题,利用不同的公式与方法解决。 1.问题描述:小A的爸爸有5万元积蓄存入

    2024年02月06日
    浏览(49)
  • pyqt 实现计算器

    文件名为:untitled.py QApplication: QApplication 类管理图形用户界面应用程序的控制流和主要设置。 可以说 QApplication是Qt的整个后台管理的命脉 app = QApplication(sys.argv)这句作用用来初始化窗口系统  app.exec(): app.exec_()的作用是运行主循环,必须调用此函数才能开始事件处理,调用该

    2024年02月16日
    浏览(42)
  • Java 实现计算器

    *使用Java语言编写一个能实现“加、减、乘、除”四则运算的计算器程序。* 要求: (1)在程序中要体现面向对象编程语言的三大特征:封装、继承和多态。 (2)该程序要易于扩展和复用。以后可以方便地增加新的运算;程序的业务逻辑与界面部分要实现分离,便于业务逻

    2024年02月12日
    浏览(39)
  • 实现复数计算器

            本论文描述了一个复数计算器的设计和实现,旨在扩展传统计算器的功能,以支持复数的加法、减法、乘法和除法。通过使用Java编程语言和Swing图形用户界面库,我们创建了一个直观、易于使用的界面,允许用户输入复数,并执行基本的算术运算。         计

    2024年02月02日
    浏览(67)
  • Android计算器实现

    这个项目是一个简单的计算器应用,它可以执行加、减、乘、除四种基本运算等计算器的基本功能。我们将使用Android Studio作为开发工具。 1. 在Android Studio中创建新的Android项目。 2. 在布局文件(`activity_main.xml`)中,我们将添加一个按钮和一个用于显示结果的文本视图。 3. 在

    2024年02月07日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包