如何为PLC定时器设置变量时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何为PLC定时器设置变量时间相关的知识,希望对你有一定的参考价值。

我使用的是西门子的PLC400现在的问题是经过了一次除法运算,需要把结果赋值给定时器的初始值,请问具体应该怎么完成,具体的程序是什么?

1、从上位机写整型数INT或实数REAL到PLC,首先该数值需包含以毫秒为单位的时间值,在写入PLC的数据存储区后,利用ITD(Integer to Double Integer)或RND(Real to Double Integer with Rounding Off)将该值转换为双整形,然后将该值写到类型为TIME的变量里,在程序中调用FC40,将TIME转换成S5TIME即可。
2、从上位机写WORD到PLC,首先该数值需包含以某时基为单位的时间值,在写入PLC的数据存储区后,用Word Logic下的WOR_W指令将该值与其时基相或,再利用MOVE指令将得到的数值写入S5TIME类型的变量中。

这是两种类型的转换
具体操作,你经过除法好 将结果 需要通过TRUNC 将浮点数->DINT;
通过传送指令将DINT->TIME;
再通过库函数FC40(库/标准库/IEC功能块/FC40)将
TIME->S5#TIME 。
明白没?追问

只有一点不懂~~就是通过TRUNC转换后的DINT数据~~应该存储在什么位置呢??似乎继续用md存储不行了吧~~~

参考技术A 程序上看没有问题,只需要把R转换为S5time就可以了,首先使用取整命令对MD26取整。找一个DB块建立一个名称为aaa 格式为 S5time 值为 S5T#100MS的变量。
使用MOVE命令把取整后的变量移动到S5TIME中就可以了,数据格式都为MB追问

不是很懂~~您的意思是得到DINT数据后,需要另外在DB块中定义一个100ms的基准值??
能不能给我说说具体流程~~~取整后的数据又应该存储为什么格式呢??MB??

追答

转换为双整形后,我们得到了一个整数,通过MOVE 把整数赋值为S5time的时间,时间单位为你在DB块里设置的单位(没有做测试,如果有PLC可以直接观察结果),这样你的S_PULSE 的TV管角就可以直接填写S5TIME时间了,格式为DB1.DBW1000(数字作为举例,实际直由你建立的变量为准)

本回答被提问者采纳
参考技术B 一个很简单的问题不知为什么你们要回答的这么复杂,这个问题分四步就可以完成
一:把运算结果值存到数据寄存器里面
二:用PLC启动ON一次的常开地址把寄存的结果传送到另一个数据寄存器里,
三:用上面那个数据寄存器直接定义定时器的时间
四:完
参考技术C 定时器这个不是很难啊,有一个子程序可以专门赋予时间啊。再用一个中间继电器连接到主程序就好了。着重定时的程序在我培训的时候经常编

如何为游戏循环制作计时器?

【中文标题】如何为游戏循环制作计时器?【英文标题】:How to make timer for a game loop? 【发布时间】:2011-03-26 09:30:53 【问题描述】:

我想计时 fps 计数,并将其限制设置为 60,但是我一直在通过谷歌查看一些代码,我完全不明白。

【问题讨论】:

出于兴趣,假设 fps 限制为 60,在 75Hz 屏幕上会是什么样子? 您可能希望在 DirectX 中打开 VSync,这会将渲染限制为屏幕刷新率的倍数。从上一帧开始花费时间并以此增加游戏状态(独立于 FPS 的世界)通常要简单得多。 【参考方案1】:

如果您想要 60 FPS,您需要计算出每帧有多少时间。在本例中,为 16.67 毫秒。因此,您需要一个每 16.67 毫秒完成一次的循环。

通常情况下(简单地说):获取输入、执行物理操作、渲染、暂停,直到 16.67 毫秒过去。

它通常通过在循环顶部保存时间,然后在结束时计算差异并在此期间休眠或循环不做任何事情来完成。

This article 描述了几种不同的游戏循环方式,包括您想要的方式,尽管我将使用本文中更高级的替代方式之一。

【讨论】:

我知道这是旧的......但链接已损坏。【参考方案2】:

增量时间是最后的时间,减去原来的时间。

dt= t-t0

不过,这个增量时间只是速度变化时经过的时间量。

一个函数的导数代表一个无穷小的变化 在函数中关于其变量之一。 函数对变量的导数定义为

                f(x + h) - f(x)
f'(x) = lim    -----------------
        h->0           h

http://mathworld.wolfram.com/Derivative.html

#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"winmm.lib")

void gotoxy(int x, int y);
void StepSimulation(float dt);

int main()

  int NewTime = 0;
  int OldTime = 0;
  float dt = 0;
  float TotalTime = 0;
  int FrameCounter = 0;
  int RENDER_FRAME_COUNT = 60;

  while(true)

        NewTime = timeGetTime();    
        dt = (float) (NewTime - OldTime)/1000; //delta time
        OldTime = NewTime;

        if (dt > (0.016f)) dt = (0.016f);  //delta time
        if (dt < 0.001f) dt = 0.001f;

        TotalTime += dt;

        if(TotalTime > 1.1f) 
            TotalTime=0;
            StepSimulation(dt);
            

        if(FrameCounter >= RENDER_FRAME_COUNT)           
            // draw stuff
            //Render(); 

            gotoxy(1,2);
            printf(" \n");
            printf("OldTime      = %d \n",OldTime);
            printf("NewTime      = %d \n",NewTime);
            printf("dt           = %f  \n",dt);
            printf("TotalTime    = %f  \n",TotalTime);
            printf("FrameCounter = %d fps\n",FrameCounter);
            printf("   \n");
            FrameCounter = 0;

         
        else
            gotoxy(22,7);
            printf("%d  ",FrameCounter);
            FrameCounter++;

        


    

    return 0;


void gotoxy(int x, int y)
    COORD coord;
    coord.X = x; coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    return;


void StepSimulation(float dt)
    // calculate stuff
   //vVelocity += Ae * dt;


【讨论】:

【参考方案3】:

您不应该尝试限制 fps。这样做的唯一原因是如果您不使用增量时间并且您希望每个帧的长度相同。即使是最简单的游戏也无法保证。

但是,您可以将增量时间切成固定大小,然后保留剩余部分。

这是我最近写的一些代码。它没有经过彻底的测试。

void GameLoop::Run()

    m_Timer.Reset();

    while(!m_Finished())
    
        Time delta = m_Timer.GetDelta();
        Time frameTime(0);
        unsigned int loopCount = 0;

        while (delta > m_TickTime && loopCount < m_MaxLoops)
        
            m_SingTick();
            delta -= m_TickTime;
            frameTime += m_TickTime;
            ++loopCount;
        
        m_Independent(frameTime);

        // add an exception flag later.
        // This is if the game hangs
        if(loopCount >= m_MaxLoops)
        
            delta %= m_TickTime;
        

        m_Render(delta);
        m_Timer.Unused(delta);
    

成员对象是 Boost 插槽,因此不同的代码可以使用不同的计时方法注册。独立插槽用于诸如键映射或更改音乐之类的不需要如此精确的事物。 SingTick 对物理学有好处,如果您知道每个滴答声都是相同的,但您不想穿过墙壁,这会更容易。渲染采用增量,因此动画运行流畅,但必须记住在下一个 SingTick 中考虑它。

希望对您有所帮助。

【讨论】:

【参考方案4】:

您不应该以这种方式限制帧速率的原因有很多。正如 stijn 指出的那样,一个原因是,并非每个显示器都可以精确地以 60fps 运行,另一个原因是计时器的分辨率不够,另一个原因是即使给定足够的分辨率,两个单独的计时器(显示器刷新和你的)也在运行由于随机的不准确,parallel 总是会与时间不同步(它们必须!),最重要的原因是它根本没有必要。

请注意,Windows 下的默认计时器分辨率是 15 毫秒,而您可以获得的最佳分辨率(通过使用 timeBeginPeriod)是 1 毫秒。因此,您可以(最多)等待 16 毫秒或 17 毫秒。 60fps 的一帧是 16.6666ms 你怎么等到 16.6666ms?

如果您想将游戏速度限制为显示器的刷新率,请启用垂直同步。这将精确地完成您想要的操作,并且不会出现同步问题。垂直同步也有其特殊性(例如当一帧需要 16.67 毫秒时您会得到有趣的惊喜),但它是迄今为止最好的解决方案。

如果您这样做的原因是为了让您的模拟适应渲染循环,那么this 是您的必读之物。

【讨论】:

【参考方案5】:

看看这个:

//Creating Digital Watch in C++
#include<iostream>
#include<Windows.h>
using namespace std;

struct time

int hr,min,sec;
;
int main()

time a;
a.hr = 0;
a.min = 0;
a.sec = 0;

for(int i = 0; i<24; i++)

    if(a.hr == 23)
    
        a.hr = 0;
    

    for(int j = 0; j<60; j++)
    
        if(a.min == 59)
        
            a.min = 0;
        

        for(int k = 0; k<60; k++)
        
            if(a.sec == 59)
            
                a.sec = 0;
            

            cout<<a.hr<<" : "<<a.min<<" : "<<a.sec<<endl;
            a.sec++;
            Sleep(1000);
            system("Cls");
        
    a.min++;



    a.hr++;



【讨论】:

看起来像一个将精确运行 24 小时的程序,并且将每秒打印小时 : 分钟 : 秒。这对游戏循环有什么好处?

以上是关于如何为PLC定时器设置变量时间的主要内容,如果未能解决你的问题,请参考以下文章

如何为vertx设置一个持久的计时器,如果服务器重新启动,它不会丢失?

如何为能量补充游戏编写计时器算法

如何为游戏循环制作计时器?

如何为 C++ 程序添加定时延迟?

哪位大侠能告知一下:在西门子PLC的有参功能块FB中如何设计定时器的功能?

西门子1200每天定时启动