Wiring Data in a State Machine

I have a state machine with about 20 cases all handling different user interactions and all completely independent of one another. That is, what one case does has nothing to do with what another does (for most of them anyway). They just execute one case and then go back to the default case. Some of them though do require data to be passed out of one case so that it can be read in another (actually not the data but just the data structure to be reused). Shift registeres work just fine of course, but this requires me to wire this data through all the other cases that don't need it just so they can have an output for the tunnel. Is there anything else I can do to avoid wiring paths through every case that doesn't actually need the data?

Here's a real simple example. I can't give you too much insight with respect to the memory usage, except to say that I've never had any problems doing things this way. I've written a couple of big vi's with 30 - 40 variables clustered this way.
Attachments:
Clustered_Variables.vi ‏35 KB

Similar Messages

  • How to save data in a state machine.

    Need to save 2 data points in a state.  Or how to add both data points from state to the array that is saved in write to file vi.  Please use the vi for reference.
    Thank you for your help.
    DOG
    Attachments:
    State.zip ‏32 KB

    I'm not entirely sure what it is that you are trying to do here, why are you trying to record the states?
    What do you mean by both data points?
    There are about a million different ways to do this many of which seem more logical then your current system, If you can explain a little we would probably be able to help a great deal more.
    If you are asking about passing out the two numbers from the User state 1 I would suggest building all of the numbers into arrays and passing them out through a concatenating exit to the while loop.
    Attachments:
    State Mod.zip ‏34 KB

  • Data acquisition in a state machine

    I've recently learned how to implement state machines, but I have a question that I haven't been able to find an aswer to.
    Question:
    How do I record uninterupted data (presently i'm using the DAQ assistant to record a single channel at 10kS/s at 1kS intervals) without interfering with my state machine?  
    Background:
    I have a time sensitive test setup (measuring pressure in a rocket chamber), and I'm using labview to both record a single pressure transducer as well as operate the valves (O2, N2, igniter, etc).  I'm using a state machine Labview architecture (just learned how).  Presently, the DAQ assistant sits in the "Idle" state, and timers (valves need to be turned on at specific times) and manual buttons control when the other states are activated.  I have a 10ms timer controlling how often each state is run, and this is the root of my concern.  
    Main concerns:
    I'm worried that:
    1)  I'm forced to change my data recording to 10ms intervals to match the 10ms timer, and
    2)  The 10ms timer will interrupt my data recording when it's in another state.  
    It's very important that the pressure data is recorded without interruption but that I have high time resolution in controlling my valves as well.
    Thoughts:
    1)  Maybe I put the 10ms timer in the "Idle" state only, and this way the other states won't interrupt the data acqusition
    2)  Maybe there is a way to completely isolate the state machine for controlling the valves and the data acqusition.  I'm not sure how to do this.
    3)  People on the forums have been talking about Queuing their data acqusition, but I'm not sure how this would benefit my situation.  
    Thanks to everyone for their feedback!

    The data acquisition and state machine timer do not have to be equal, you should however have the same data write rate as you have data read rate, otherwise over the course of long running programs you can build up a large buffer of data to be written using a lot of memory, or lose data.
    Your data acquisition should be continuous, the most common way of doing this is every time you receive data write it to a queue, then when you are in other states except your data write stage you simply build up data in the queue that is to be written when you enter the write state again.
    Think of it as traffic reaching a set of lights:
    The traffic represents the data acquisition, there is a constant flow of it always coming through, the state of your state machine is the lights, green is the data write state clearing the queue, red is when in any other state, letting the traffic build up behind the lights.
    It is just important that the light is green long enough to let the traffic not build up too much, otherwise you have a jam.
    EDIT: For the basics of how queues work, look at the Queue basics example from the example finder. 

  • Simple state machine Where to begin?

    Hello
    Got a question that is simple for the experienced people here I guess. But don't know where to start..... Here is what I want to try to do:
    I have got a lot of inputs, to keep the question simple I have only drawn a few of them but eventually there will be tens of inputs. For now I will only use the front panel and no real IO box (hardware), just to see if I can make a State machine that can handle this "problem" in a organized / proper way.
    What I want is to do is read a sensor, for example sensor B1 and multiply it with the multiplication factor (column Process input) and show the result on the front panel.
    There will be different types of sensors, some need multiplication, others sensors need just a constant be added to the input before the result is shown in the Result column etc.Of every sensor there will be a lot, so just wiring them all in one place will create chaos, and I don't like chaos (only dr chaos in South park is fun but I would not have him in my labview code either).
    Can anyone tell me how to approach this "problem" ?
    Thank you for the advice!!

    Hello altenbach,
    thank you for your reply,
    I think the question might not have been completely clear. I can devide the question in different parts I think. I will give it a try lets see
    (1)There Will be a lot of sensors and a lot of different type of sensors. There will be sensors that behave:
    (A)as a switch Called them Type A in the picture
    (B)as a voltage source For example mV per degree celcius
    and then there are more
    (C)sensors that behave as a current source
    (D)and a other type of sensor
    ow noooo there are more
    and even more
    (K)sensors that have got a voltage output but measure something else as B for example a distance.
    Of every type of sensor there will be more than 1 sensors. So there could be 10 sensors of type A 8 of type B 15 of type C etc. It would also be nice to ad or remove a sensor after a while.
    The sensors need to have a usefull name. Like "Temperature in chamber A". I want to be able to use this name everywhere in the code. So I if I need to process the "Temperature in chamber A" I want to have a human readable name. (type def?).
    I think I need to have a other name to indentiefie what kind of sensor it is: temperature, distance etc. This would make it easier to make a subfunction or SM deciding how to handle this information.
    So I think the question should be how can I make a big highway of data comming out of the front pannel in one wire, If I have wire's A till K the code will become unreadable. I was thinking of some kind a arry of strucs?
    I tried to keep the qestion as simple as possible at first but maybe it made it too unclear I think the question might sugest it will stay a simple program but it will not, it is just a first step.
    The first step I want to try is to just multiply a voltage with a number (just to test the functioning of the supper-highway of data).
    If I know that that works I will try this superhighway of data in a State machine then the value will to be prosseced in different ways.
    After that I hope to have the Hardware IO It is a NON FPGA frame with a few cards in it from NI, cabable of measuring digital IO analog IO etc analog output etc. So at that point the frontpannel will be party replaced for the HArdware IO. As I want to test the software in different stages of development I first wanted to start simple so I could test the written software in different stages of development.
    So can anyone tell me how to get this supperhighway of data out of the fron pannel?
    I hope the question is a clear, if not just ask.
    Thank you for the help so far!!

  • Tips to remember when using Queued State machine

    I have been able to work through to convert my State Machine architecture to a QSM thereby eliminating using Local variables/property nodes to send values/data to my State machine but instead sending them through queues.
    I would like some tips/advice on making use of them perfectly. Especially, "Not to do" stuff with queues and How to efficiently release a queue etc. What is the convention when using queues? Thanks!
    V
    I may not be perfect, but I'm all I got!
    Solved!
    Go to Solution.

    VeeJay wrote:
    Hmmm!! I jumped the gun... I would have to say, Neither... I guess it isn't really QSM or Queued message handler. My State machine is the generic one. But, data for the SM is obtained from a queue and feedback is sent back from the State machine through a queue. Does that clarify ?
    BTW, good to know more variations.. Thanks!
    That is a QSM.
    I will defer to those that use them regularly.
    I would only use such a a construct if the queue was limited to a single entry and prevented inserting multiple states at the front or back of the queue.
    As long as the queue is limited to a single entry then a State Transition Diagram could be used to described all of the states.
    The multiple entry version can be thought of as a method to implement a "goto" statement in LV. Very useful for those that come from a background working with stacks and pushing and popping off work and those that use them often love them.
    But for me let me refer to a letter from Dijkstra quote from here
    "GOTO Staements Concidered Harmful" goto statement introduces chaos
    Ben
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction

  • Data acquisition & state machine

    Hi all,
    I am working on a project that is capable of data acquisition, analyse, and record processes. I have to acquire data of temperature from 8-32 channels and that of pressure from 7 channels. After analysis, I have 48 outputs. I want to record raw data (acquired) and analysis data at the same time.
    1) Is it possible to record two text files (raw data and analysis data records) at the same time?
    I also want to adjust acquired sample rate but I have doubts about utilizing it in a state machine. For now, I have just used time elapsed function to acquire data once in 60 seconds.
    2) How could I set sample rate of acquisition except using time elapsed function?
    I also have one more doubt about timing. If I needed to acquire sample once in 60 seconds, but the analysis took more than 60 secs, what would happen?
    3) How can I prevent data loss in this case?
    I have not prepared a user interface yet.
    4) How can I utilize it? Do I put graphs and indicaters in the same VI or is it better to prepare another vi just for user interface?
    Thanks in advance
    Egemen
    Attachments:
    Program.llb ‏433 KB

    Hi Egemen
    -          If we need to acquire data and analyze it at the same time we recommend the architecture producer-consumer to prevent data loss, and yes you can record two text files at the same time. Please take a look to this architecture.
    -          http://www.ni.com/white-paper/3023/en
    -          Basically you use the first loop to acquire data and the second one to analyze and record data (using queues).
    -          https://decibel.ni.com/content/docs/DOC-2431
    -          You can also find examples about this architecture at the developer zone.
    Regards

  • How do I add new data to the same file in a State Machine?

    Hello,
    I have a State Machine, with a State where 3 samples of data are collected in a For Loop. I would like to save this data in a file and keep adding new data to the same file each time I get to this state. The problem I'm running into is that each time I reach this State, my old data in the Excel file gets replaced with the new data instead of being continuously added in the same file.
    Ive tried Shift Registers but I may not be using them correctly since my file keeps displaying only 3 new data points.
    Any ideas will be appreciated!
    Thank you, so much.
    -Peter

    Where should I place these shift registers? Where should I place my File I/O VIs? Is it possible to use the Write to Spreadsheet File VI in this situation?
    Ive attached a very simple example of the problem. Thank you.
    Attachments:
    StandardStateMachine 2.vi ‏16 KB

  • Best method for state machine design for multi-dimensional clustered data

    I have an application that is collecting analog tag data(1000 points) and displaying on a graph. In each vi, I may collect data for as many as 32 channels, but only one channel at a time. Usually this is collected in numeric order, but maybe not all the time. I am also saving an "expected profile" to a file for each channel. I display both expected and actual data on the graph and select which channel to view with a ring control. My question is about how to design the state machine for best memory usage/execution speed/... If I use a shift register with a cluster datatype, that holds both 1000 point arrays, some statistical data like max/min/pass/fail/test limits for 32 channels, won't all of the u
    nbundle/bundle functions use a ton of memory??? Right now I am writing the cluster data to memory tags for each channel. I use the ring control to determine which tag to read. I have the tags grouped by channel into several groups for actual data, expected data, results data,... What design methods would provide the best function using a shift register/queues and notifiers/memory tags in the tag engine?? I also use CITADEL to read the max and average as a trend display on each channel and to select a specific 1000 point dataset to view if the max and average are out of limits. Does anyone have similar applications??

    It sounds as if you will be working with alot of data here so I can understand your concerns for memory management. If you were to unbundle and bundle data in your application, you are correct in saying that it will require more memory. It is somewhat difficult to get the overall picture of what you are needing to set up, but from what I can gather, it sounds as if you could have an array of 32 elements; each element a cluster of your data as well as the statistical data, and then you could index through that array to determine what to display on the graph. The shift registers will be reusing the same memory over and over so there should not be a problem there. Queues wouldn't necessarily help you in any way in this situation. Depending on how many memory tag
    s you are using, you could increase the amount of memory usage required by Citadel and the tag engine, but if you are needing to write your cluster data to the database, then there is not much you can do about it. Ultimately it sounds like a pretty involved application and will require a fair amount of memory regardless to ensure smooth functionality.
    In general, questions about the LabVIEW architecture and memory management are typically better answered if they are posted to the general LabVIEW discussion forum area. But I hope that this has addressed some of your concerns. Have a good day.
    Patrick R.

  • Data between states of the states machine

    So I have two tables that I generate in one state of the state machine.  My question is what is a proper, aesthetic way to propogate these two tables into one another state of the state machine. Please see the attached  code.  State machines rock!
    Attachments:
    flag.jpg ‏166 KB

    The shift register is the right tool for this job.  It follows the left to right data flow paradigm, unlike other solutions (such as using a local variable).  I am sure you will get a few other opinions but I think that the shift register is the way to go.
    CLA, CLED, CTD,CPI, LabVIEW Champion
    Platinum Alliance Partner
    Senior Engineer
    Using LV 2013, 2012
    Don't forget Kudos for Good Answers, and Mark a solution if your problem is solved.

  • How to transfer data between the different states in "state machine"?

    I want to transfer some data from one state to another. I tried the tunnel, but it can't work since it's the case structure. Does "state machince" support data transfer? Or any other methods I can do?
    Thank you.

    Yes, adding a shift register to the outer while loop should work, make sure to initialize it.  Perhaps you could attach your vi so we could have a look at it.  Be sure to give us as much info as to what your goal for the vi is.
    Cheers!
    CLA, CLED, CTD,CPI, LabVIEW Champion
    Platinum Alliance Partner
    Senior Engineer
    Using LV 2013, 2012
    Don't forget Kudos for Good Answers, and Mark a solution if your problem is solved.

  • Wiring constants into the queue in a queued, event driven state machine

    I'm creating a queued state machine. Every time I change the queue control options to create a new event I have to recreate a constant in each queued event. Is there a way around this? I'm up to 27 events and changing them all is cumbersome. And I'm sure there are more to folow.

    Are you using enums for your constants? If so, make a control from one, right click on it and under "advanced" select "customize" and when in the control editor change the pulldown from "Control" to "Type def." Save it with a useful name, and then in the vi in which you originally created it, use it to create a new constant. You will be able to select the different constant values were you need them and now when you want to add or subtract a "named" value you just click on the closest copy of the type def, either control or diagram constant, and choose customize (or double click into the tool editor if you made that choice in the options in the Tool pulldown at the top of the screen). Any changes you make will automatically be replicated everywhere you have used the typedef, whether a control, indicator or constant. Using enums also allows having case statements that have cases with the same names at the "named" value.
    Hope this helps and is what you were refering too.
    Putnam Monroe
    Certified LabVIEW Developer
    Putnam
    Certified LabVIEW Developer
    Senior Test Engineer
    Currently using LV 6.1-LabVIEW 2012, RT8.5
    LabVIEW Champion

  • Problems closing several loops in a state machine with an event structure

    I am having some problems closing three loops running in parallel in a state machine.  I have one loop for an event structure to monitor user controls to change the state.  The other loop is the state machine which will control an actuator, and the third loop is for data aquisition/analysis.  I want to be able to hit the stop button and go to a "shutdown" state where I can home the actuator then close the loops and finally go to the last "shutdown" subdiagriam in the flat sequence structure.  Currently when hitting the stop button it goes into the shutdown state and will end the state machine loop but it appears the other loops are not closing until I hit the stop button again.  Could this be due to using a local variable for the boolean to control the loop conditions? I attached a screenshot of the block diagram.  Any advice would be great!
    Attachments:
    example.png ‏108 KB

    You have a classic race condition due to overuse of local variables. If the stop event fires in the upper loop, the local variable connected to the loop termination condition has already been read (it is false!). This means that the upper loop will iterate once more and again wait at the event structure for the next event. At this time, the local variable connected to the loop termination is TRUE, but the loop cannot complete until the event fires again, for example if you press the stop button once more.
    The correct way is to connect the terminal of the stop button across the right event frame directly to the loop termination terminal. Now it will get the TRUE value correctly once the stop event fires for the first time.
    LabVIEW does not execute left to right, execution order is determined by the wiring.
    I also agree with the above message that you should rethink and re-architect your code using established coding guidelines. 
    LabVIEW Champion . Do more with less code and in less time .

  • Help with cycling sequence structure, I may need a state machine?

    Hi All,
    So I have this VI that needs to control two solenoid valves by opening and closing them through the digital outputs.
    I want the program to have a function like this
    Phase 1: Valve 1 open, Valve 2 closed (Amount of time for this defined by user)
    Phase 2: Both valves closed (for .1 seconds)
    Phase 3: Valve 1 closed, Valve 2 open (Again, this amount of time is defined by user)
    and I want it to cycle through phase 1-3 100,000 times. However, every 10,000 cycles of phase 1-3 I want it to change the condition on Phase 2 so that both valves are closed for an hour instead of .1 seconds, then after this hour loop I want it to return back to the original cycling conditions (.1 sec instead of 1 hour) until it does another 10,000 cycles.
    I was thinking that a sequence loop would be fine because I would wire it up with timing and a counter, and every time it goes to the last sequence it would increase the counter so that when its at the phase 2 timing I can use a case structure (if counter > 10,000 hold 1 hour, if counter <10,000 hold .1 sec) and then in the last sequence reset the counter to 1 if it is >10,000.
    I thought a sequence structure would be good for this but I'm fairly new to labview and if theres a better way to do this I'm open to suggestions .
    Attached is my code so far, except that I have not finished wiring the ports for valve B
    Attachments:
    Adhesive Pressure Cycling.vi ‏100 KB

    First, you should avoid the use of a sequence structure. Don't even consider it to be an option. At least not at this stage of your learning. Learn how to use data flow. Also, avoid the use of local/global variables. They tend to lead to race conditions which in turn result in some difficult bugs to find and fix. Think of the wires as your variables.
    As for the time delay in your state machine, your actual state should delay for a short time like 100 ms. Use the current time of day to determine when you have reached your desired timeout. If you use a single delay of an hour your program will be unresponsive for that hour. Users tend to get very annoyed if they try to stop the program and they have to wait a long time for it to actually stop.
    Here is a basic example that shows the concept in a state machine.
    When naming states for your state machine give them a meanigful name. Use a typedefed ENUM for your state variable. For simplicity sake the example attached does not use a typedef. But naming things like State 1, State 2 and so on makes the code difficult to read and understand. Your Open/Close valves states can be written in such a way that they are generic and take the valve data as input. At a minimum I would create a subVI to do this so you only have one piece of code to manage. You could have explcit states though such as Open Valve A and Open Valve B that call your generic Open Vavle subVI with the appropriate input data.
    One last comment, the express VIs tend to be very inefficient. They are OK for learning how things are done but I would implement their functionality directly. For example, the express VIs tend to open, initialize, do something, close the instrument. You really don't have to do all of that every time. Open and Initialize once in the begining (hint, this could be a state), put the stuff that does the work in appropriate states/subVIs (other states) and then close at the end of your application (the exit state for example).
    Mark Yedinak
    "Does anyone know where the love of God goes when the waves turn the minutes to hours?"
    Wreck of the Edmund Fitzgerald - Gordon Lightfoot
    Attachments:
    Simple Delay in State Machine.vi ‏15 KB

  • How can I keep a state machine readable when using large amounts of in/outputs

    Hello, I am new to Labview,
    Read trough the fundamentals and the
    getting started and a lot of examples.
    What I want to do is use a standard
    state machine from the template, and add some stages, for example
    orange, apple, banana. At this point I can use numeric controls to
    put in the amount of oranges, apples, bananas there are. I can even
    use a led to tell the user which state of the state-machine is
    active.
    The thing is there will be more numeric
    controls and more leds and it would be nice if the code would still
    be readable when there are 20 inputs and 20 outputs.
    Questions
    (1) It would be nice if I could use the
    typedef to select the right state AND the corresponding numeric
    controls and leds out of a cluster or an array kind of structure to
    keep the number of wires low. Is this possible, how can I do this?
    (2) I tried to put the numeric controls
    into a cluster but that way I can't put the numeric control for the
    apples in the upper right corner and the numeric control for the
    oranges in the lower left down corner of the front panel.
    (3) An example would be really nice, I
    know that I saw some examples describing this problem but there are
    so many examples that after a few hours of searching I haven't found
    the right one yet.
    Thanks in advance for the effort.
    p.s. I will not use Labview to do
    calculations on fruit, I am only using this to make the question
    easier to understand.

    I can only start a proper answer but I might as well start with that.
    When I am developing State Machines I have to think about what data is used and manipulated in each state. I then have to think about where am i going to keep and manage the data. I list all of the fields that are "touched" in each state and what values are used together and which are independent form the others. After this phase of the analysis, I usually have some data structure defined (cluser array etc).
    Then I flipp from thinking about the state to thinking about the data (after all this is LabVIEW and the data-flow paradigm is critical). If I see data that is only used by the State machine and is used in many of the states, then the data structure get put in a shift-register for easy access in each state. This maybe enough of an answer for your fruity question.
    When i see data that is shared or only used in a handful of states then I concider putting the data in an Action Engine. Depending on how you design your AE, you can access each of the fruit totoal by name or increment etc as required.
    If your app demands many fileds that are all related (can't be broken into distinct data structures) then create a cluster that has all of your values that are used by the AE. Then create an Wrapper VI for each call of the AE but only put the associated fields on the FP of the wrapper and then bundle that value into the cluster and invoke the AE.
    Ben
    PS: Sorry about reverting to neBulus mode but this topic could take days to cover in detail.
    Ben Rayner
    I am currently active on.. MainStream Preppers
    Rayner's Ridge is under construction

  • Relay Testing with State Machine

    Hi,
    Yesterday I very kindly had some help from "crossrulz" in setting out the following procedure.  Today, the National Instruments representative called and said I should implement my programme as a "State Machine", which I have attempted in the programme attached.  I was wondering how I might now implement the procedures 3 to 5 in this State Machine format as it seemed very complecated in the brief time we had. 
    What I am trying to do is test relays, using an automated test procedure.
    The procedure takes the following steps:
    1.       A NI9472  DO card and transistor drive turns the relay on/off via energising the coil (needs the time period to be variable).
    2.       Counts how may cycles the relay contacts have operated, this will easily be in excess of 100,000 cycles.
    3.       Every 100 cycles (again variable), the contacts are held closed, the load circuit (the current the relay is switching, which will be 15A at 30V) is disconnected, via another relay and a measurement is taken via a separate four wire method.  This consists of a 6V supply being placed across the contacts (switched in again via a relay) with a 1A current flowing through the contacts, the voltage drop across the contacts is then inputted into the NI AI NI9219 card (this is in the region of 10’s of mA) and is directly proportional to the contact resistance, which is what I want to measure.
    4.       The measurement is taken and stored and the measurement circuit disengaged, the load circuit re-engaged, and another 100 cycles is counted before the process goes back to stage 3.
    5.       This process goes on until the relay fails and hopefully a large set of contact resistance data is gathered.
    I have no real experience with NI Labview.  
    I have looked at the basic academic tutorials and have come up with the following programme for stage 1, however I can't get the DAQ Assistant to output every cycle
    Would this be a very difficult programme to implement for the novice?  The academic tutorials seem straight forward but when I try to do someting it seems very difficult.
    Hoping someone may be able to help, thanks
    Andy
    Solved!
    Go to Solution.
    Attachments:
    Relay Test State Machine.vi ‏207 KB
    Relay Test State Machine.vi ‏207 KB

    Hi James,
    I've tried to implement some logic as suggested.  I can now get the 1A coil to engauge after the nth cycle and I think it's taking a measurement, but can't seem to get the 15 A coil to disengauge at the same moment, which is crucial else the measurement will be across 16 A rather than just the 1 A.  Any ideas?  I just want to get it working so we can get started with testing.
    I'm going to get my supervisor to book me on a course at Newbury for future projects, it's very difficult to pick up of your own back.
    Kind regards,
    Andy
    (Helps if I attach it)
    Attachments:
    Relay Test State Machine.vi ‏209 KB

Maybe you are looking for

  • Hovering over things doesn't work

    So I have had my MacBook Pro for a solid 1 1/2 years, and I am very satisfied with apple. However, recently my macbook started doing this thing, where when I hovered over something (say, my dock), it wouldn't think im hovering over it until I clicked

  • Lockbox issue - Very urgent....

    Hi all, If a payment from the lockbox file is erroneously put ‘On account” for a customer since it was unprocessed and later the user has realized that the payment does not belong to that customer also it is not related to any customer so, he wants t

  • DHCP_TIMEOUT in /etc/conf.d/netcfg has no effect

    I want to set DHCP_TIMEOUT to 30 for all netcfg profiles. On  this page in wiki it is suggested to set the variable in /etc/conf.d/netcfg. But this has no effect. I tried 'NETCFG_DEBUG="yes" netcfg <arguments>' and the timeout was still 10. How can I

  • Function Module to Edit Billing Document Header (table VBRK)

    Hi all, Can someone tell me if there is a function module that can edit the billing document header please?  I do not need to created the billing document, it already exists.  I just need to edit specific fields. Many thanks.

  • IChat Video Encryption

    Hello Everybody I have a family account for MobileMe and each account has a security certificate so we can chat securely. When we are text chatting both mine and the other persons chat window show a black closed padlock and it says the chat is encryp